diff options
Diffstat (limited to 'common')
-rwxr-xr-x | common/include/media-server-common.h | 153 | ||||
-rwxr-xr-x | common/include/media-server-error.h | 91 | ||||
-rwxr-xr-x | common/include/media-server-global.h | 123 | ||||
-rwxr-xr-x | common/include/media-server-hibernation.h | 40 | ||||
-rwxr-xr-x | common/include/media-server-inotify-internal.h | 56 | ||||
-rwxr-xr-x | common/include/media-server-inotify.h | 63 | ||||
-rwxr-xr-x | common/include/media-server-scan-internal.h | 38 | ||||
-rwxr-xr-x | common/include/media-server-scan.h | 31 | ||||
-rwxr-xr-x | common/include/media-server-socket.h | 34 | ||||
-rwxr-xr-x | common/include/media-server-thumb.h | 35 | ||||
-rwxr-xr-x | common/include/media-server-types.h | 99 | ||||
-rwxr-xr-x | common/media-server-common.c | 1780 | ||||
-rwxr-xr-x | common/media-server-hibernation.c | 132 | ||||
-rwxr-xr-x | common/media-server-inotify-internal.c | 142 | ||||
-rwxr-xr-x | common/media-server-inotify.c | 707 | ||||
-rwxr-xr-x | common/media-server-main.c | 240 | ||||
-rwxr-xr-x | common/media-server-scan-internal.c | 404 | ||||
-rwxr-xr-x | common/media-server-scan.c | 239 | ||||
-rwxr-xr-x | common/media-server-socket.c | 147 | ||||
-rwxr-xr-x | common/media-server-thumb.c | 108 |
20 files changed, 4662 insertions, 0 deletions
diff --git a/common/include/media-server-common.h b/common/include/media-server-common.h new file mode 100755 index 0000000..68daba6 --- /dev/null +++ b/common/include/media-server-common.h @@ -0,0 +1,153 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-common.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef __FEXPLORER_ENGINE_DB_PUBLIC_H__ +#define __FEXPLORER_ENGINE_DB_PUBLIC_H__ + +#include <sqlite3.h> +#include "media-server-global.h" + +#define MS_SQL_MAX_LEN 4096 + +int ms_update_valid_type(char *path); + +int ms_set_db_status(ms_db_status_type_t status); + +int ms_db_init(bool need_db_create); + +int ms_media_db_open(void); + +int ms_media_db_close(void); + +int ms_update_mmc_info(void); + +void ms_mmc_removed_handler(void); + +void ms_mmc_vconf_cb(void *data); + +bool ms_is_mmc_supported(void); + +ms_dir_scan_type_t ms_get_mmc_state(void); + +void ms_usb_vconf_cb(void *data); + +void ms_register_start(void); + +void ms_register_end(void); + +int ms_register_file(const char *path, GAsyncQueue* queue); + +int ms_register_scanfile(const char *path); + +int ms_start(bool need_db_create); + +void ms_end(void); + +int ms_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path); + +ms_store_type_t ms_get_store_type_by_full(const char *path); + +int ms_strappend(char *res, const int size, const char *pattern, + const char *str1, const char *str2); + +int ms_strcopy(char *res, const int size, const char *pattern, + const char *str1); + +#ifdef _WITH_SETTING_AND_NOTI_ +bool ms_config_get_int(const char *key, int *value); + +bool ms_config_set_int(const char *key, int value); + +bool ms_config_get_str(const char *key, char *value); + +bool ms_config_set_str(const char *key, const char *value); +#endif + +void ms_check_db_updating(void); + +int ms_get_category_from_mime(const char *path, int *category); + +bool fex_make_default_path(void); + +bool fex_make_default_path_mmc(void); + +/**************************************************************************************************** +LIBMEDIA_INFO +*****************************************************************************************************/ +#ifdef _WITH_MP_PB_ + +void ms_update_valid_type_start(void); + +void ms_update_valid_type_end(void); + +int ms_change_valid_type(ms_store_type_t table_id, bool validation); +#ifdef THUMB_THREAD +int ms_media_db_insert_with_thumb(const char *path, int category); +#endif +int ms_media_db_insert(const char *path, int category, bool bulk); + +int ms_check_file_exist_in_db(const char *file_full_path); + +int ms_media_db_delete(const char *full_file_path); + +void ms_media_db_move_start(void); + +void ms_media_db_move_end(void); + +int ms_media_db_move(ms_store_type_t src_store_type, + ms_store_type_t dest_store_type, + const char *src_file_full_path, + const char *dest_file_full_path); + +bool ms_delete_all_record(ms_store_type_t store_type); + +#ifdef FMS_PERF +void ms_check_start_time(struct timeval *start_time); + +void ms_check_end_time(struct timeval *end_time); + +void ms_check_time_diff(struct timeval *start_time, struct timeval *end_time); +#endif /*FMS_PERF */ +#endif/*_WITH_MP_PB_*/ + +#ifdef PROGRESS +struct quickpanel; + +void ms_create_quickpanel(struct quickpanel *ms_quickpanel); + +void ms_update_progress(struct quickpanel *ms_quickpanel, double progress); + +void ms_delete_quickpanel(struct quickpanel *ms_quickpanel); +#endif /*PROGRSS*/ +/** + * @} + */ +#endif /*__FEXPLORER_ENGINE_DB_PUBLIC_H__*/ + diff --git a/common/include/media-server-error.h b/common/include/media-server-error.h new file mode 100755 index 0000000..131a273 --- /dev/null +++ b/common/include/media-server-error.h @@ -0,0 +1,91 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-error.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef _FEXPLORER_ENGINE_ERROR_H_ +#define _FEXPLORER_ENGINE_ERROR_H_ + +#define ERROR_MASKL16 0xFFFF +#define ERROR(X) (X & ERROR_MASKL16) + +#define MID_CONTENTS_MGR_ERROR 0 /*MID_CONTENTS_MGR_SERVICE */ + +#define MS_ERR_NONE 0 + +/*internal operation error*/ +#define MS_ERR_ARG_INVALID (MID_CONTENTS_MGR_ERROR - ERROR(0x01)) /**< invalid argument */ +#define MS_ERR_ALLOCATE_MEMORY_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x02)) /**< exception of memory allocation */ +#define MS_ERR_OUT_OF_RANGE (MID_CONTENTS_MGR_ERROR - ERROR(0x03)) +#define MS_ERR_INVALID_DIR_PATH (MID_CONTENTS_MGR_ERROR - ERROR(0x04)) /**< exception of invalid dir path */ +#define MS_ERR_INVALID_FILE_PATH (MID_CONTENTS_MGR_ERROR - ERROR(0x05)) /**< exception of invalid file path */ +#define MS_ERR_NOW_REGISTER_FILE (MID_CONTENTS_MGR_ERROR - ERROR(0x06)) /**< exception of invalid file path */ + +/*directory operation error*/ +#define MS_ERR_DIR_OPEN_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x10)) /**< exception of dir open*/ +#define MS_ERR_DIR_NOT_FOUND (MID_CONTENTS_MGR_ERROR - ERROR(0x11)) /**< exception of dir doesn't exist*/ +#define MS_ERR_DIR_READ_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x13)) /**< exception of dir read*/ + +/*file operation error*/ +#define MS_ERR_FILE_NOT_FOUND (MID_CONTENTS_MGR_ERROR - ERROR(0x20)) /**< exception of file doesn't exist*/ +#define MS_ERR_FILE_OPEN_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x21)) /**< exception of file doesn't exist*/ + +/*db operation error*/ +#define MS_ERR_DB_TRUNCATE_TABLE_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x30)) /**< truncating table fails */ +#define MS_ERR_DB_INSERT_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x31)) /**< inserting record fails */ +#define MS_ERR_DB_DELETE_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x32)) /**< deleting record fails */ +#define MS_ERR_DB_UPDATE_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x33)) /**< updating record fails */ +#define MS_ERR_DB_CONNECT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x34)) /**< connecting database fails */ +#define MS_ERR_DB_DISCONNECT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x35)) /**< connecting database fails */ +#define MS_ERR_DB_OPERATION_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x36)) /**< connecting database fails */ + +/*drm operation error*/ +#define MS_ERR_DRM_GET_TYPE (MID_CONTENTS_MGR_ERROR - ERROR(0x40)) +#define MS_ERR_DRM_MOVE_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x41)) /**< can't copy/move drm file because of permission */ +#define MS_ERR_DRM_REGISTER_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x42)) +#define MS_ERR_DRM_EXTRACT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x43)) + +/*IPC operation error*/ +#define MS_ERR_SOCKET_CONN (MID_CONTENTS_MGR_ERROR - ERROR(0x50)) /**< Socket connect error */ +#define MS_ERR_SOCKET_BIND (MID_CONTENTS_MGR_ERROR - ERROR(0x51)) /**< Socket connect error */ +#define MS_ERR_SOCKET_MSG (MID_CONTENTS_MGR_ERROR - ERROR(0x52)) /**< Socket message error */ +#define MS_ERR_SOCKET_SEND (MID_CONTENTS_MGR_ERROR - ERROR(0x53)) /**< Socket send error */ +#define MS_ERR_SOCKET_RECEIVE (MID_CONTENTS_MGR_ERROR - ERROR(0x54)) /**< Socket receive error */ + +/*ETC*/ +#define MS_ERR_LOW_MEMORY (MID_CONTENTS_MGR_ERROR - ERROR(0x60)) /**< low memory*/ +#define MS_ERR_UNKNOWN_ERROR (MID_CONTENTS_MGR_ERROR - ERROR(0x61)) /**< unknow error*/ +#define MS_ERR_VCONF_SET_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x62)) /**< vconf set fail*/ +#define MS_ERR_VCONF_GET_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x63)) /**< vconf get fail*/ +#define MS_ERR_NOT_MEDIA_FILE (MID_CONTENTS_MGR_ERROR - ERROR(0x64)) /**< not media file*/ + +#define MS_ERR_MAX (MID_CONTENTS_MGR_ERROR - ERROR(0xff)) /**< Max count*/ +#endif /* _FEXPLORER_ENGINE_ERROR_H_ */ +/** + * @} + */ diff --git a/common/include/media-server-global.h b/common/include/media-server-global.h new file mode 100755 index 0000000..a3c588e --- /dev/null +++ b/common/include/media-server-global.h @@ -0,0 +1,123 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-global.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef _FEXPLORER_ENGINEGLOBAL_H_ +#define _FEXPLORER_ENGINEGLOBAL_H_ +#include <malloc.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <time.h> +#include <stdbool.h> +#include <unistd.h> +#include <glib.h> +#include <fcntl.h> +#include <dirent.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <sys/vfs.h> +#include <sys/syscall.h> +#include <dlfcn.h> +#include <errno.h> + +#include <dlog.h> + +#include "media-server-error.h" +#include "media-server-types.h" + +#define _WITH_MP_PB_ +#define _WITH_DRM_SERVICE_ /*drm-servic3 */ +#define _WITH_SETTING_AND_NOTI_ /*replace gconf-dbus */ +#define FMS_PERF + +/* To enable hibernation callback */ +/*#define _USE_HIB*/ + +/* To enable progress bar in quickpanel */ +/*#define PROGRESS*/ + +/* To enable thumbnail thread*/ +/*#define THUMB_THREAD*/ + +#define FEXPLORER_DEBUG +#ifndef DEPRECATED /*temp definition for deprecated */ +#define DEPRECATED __attribute__((deprecated)) +#endif + +#ifdef FEXPLORER_DEBUG +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "MEDIA-SERVER" +#define MS_DBG_START() LOGD("[%d, %s-%d] ========[ START ]========\n" , syscall(__NR_gettid), __func__ , __LINE__); +#define MS_DBG_END() LOGD("[%d, %s-%d] ========[ END ]========\n" ,syscall(__NR_gettid), __func__ , __LINE__); +#define MS_DBG_FUNC_LINE() LOGD("[%s-%d] debug\n" , __func__ , __LINE__); +#define MS_DBG(fmt, args...) LOGD("[%d, %s-%d] " fmt "\n" , syscall(__NR_gettid), __func__ , __LINE__ , ##args); +#endif /*FEXPLORER_DEBUG */ + +#define MS_DRM_CONTENT_TYPE_LENGTH 100 +#define MS_REGISTER_COUNT 100 /*For bundle commit*/ +#define MS_VALID_COUNT 100 /*For bundle commit*/ +#define MS_MOVE_COUNT 100 /*For bundle commit*/ + +/* in case of 32 bytes machine*/ +#define DUMMY_FIELD_LEN_32(n) ((((n-1) / 8 + 1) * 2) / sizeof(long) + 6) + +#define MALLOC(a) malloc(a) +#define FREE(a) free(a) + +#define MS_PHONE_ROOT_PATH "opt/media" +#define MS_MMC_ROOT_PATH "opt/storage/sdcard" +#define MS_DB_UPDATE_NOTI_PATH "/opt/data/file-manager-service" + +#define end_thread 100 + +/*This macro is used to check the lastest usb mode*/ +#define MS_USB_MODE_KEY "db/Apps/mediaserver/usbmode" +enum { + MS_VCONFKEY_NORMAL_MODE = 0x00, + MS_VCONFKEY_MASS_STORAGE_MODE = 0x01 +}; +#define MS_MMC_INFO_KEY "db/Apps/mediaserver/mmc_info" + +#define MS_THUMB_STATUS "db/Apps/mediaserver/thumb_status" +enum { + MS_VCONFKEY_THUMB_NONE = 0x00, + MS_VCONFKEY_THUMB_PAUSE = 0x01, + MS_VCONFKEY_THUMB_RESUME = 0x02 +}; +/** + * @} + */ + +#endif /*_FEXPLORER_ENGINEGLOBAL_H_*/ diff --git a/common/include/media-server-hibernation.h b/common/include/media-server-hibernation.h new file mode 100755 index 0000000..53976ce --- /dev/null +++ b/common/include/media-server-hibernation.h @@ -0,0 +1,40 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-hibernation.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#ifdef _USE_HIB +#ifndef _FEXPLORER_ENGINE_HIB_H_ +#define _FEXPLORER_ENGINE_HIB_H_ + +int _hibernation_initialize(void); + +void _hibernation_fianalize(void); + +#endif /* _FEXPLORER_ENGINE_HIB_H_ */ +#endif diff --git a/common/include/media-server-inotify-internal.h b/common/include/media-server-inotify-internal.h new file mode 100755 index 0000000..88548be --- /dev/null +++ b/common/include/media-server-inotify-internal.h @@ -0,0 +1,56 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-inotify-internal.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include <sys/inotify.h> +#include <sqlite3.h> +#include <drm-service.h> + +#define INOTI_EVENT_SIZE (sizeof(struct inotify_event)) +#define INOTI_BUF_LEN (1024*(INOTI_EVENT_SIZE+16)) +#define INOTI_FOLDER_COUNT_MAX 1024 + +typedef struct ms_create_file_info { + char *name; + int wd; + struct ms_create_file_info *previous; + struct ms_create_file_info *next; +} ms_create_file_info; + +int _ms_inoti_add_create_file_list(int wd, char *name); + +int _ms_inoti_delete_create_file_list(ms_create_file_info *node); + +ms_create_file_info *_ms_inoti_find_create_file_list(int wd, char *name); + +int _fex_is_default_path(const char *path); + +bool _ms_inoti_full_path(int wd, char *name, char *path, int sizeofpath); + +bool _ms_inoti_get_full_path(int wd, char *name, char *path, int sizeofpath); + diff --git a/common/include/media-server-inotify.h b/common/include/media-server-inotify.h new file mode 100755 index 0000000..184a599 --- /dev/null +++ b/common/include/media-server-inotify.h @@ -0,0 +1,63 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-inotify.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef _FEXPLORER_ENGINE_INOTI_H_ +#define _FEXPLORER_ENGINE_INOTI_H_ + +#include <glib.h> + +typedef struct ms_ignore_file_info { + char *path; + struct ms_ignore_file_info *previous; + struct ms_ignore_file_info *next; +} ms_ignore_file_info; + +int ms_inoti_init(void); + +gboolean ms_inoti_thread(gpointer data); + +void ms_inoti_add_watch(char *path); + +int ms_inoti_add_watch_with_node(ms_dir_scan_info * const current_node); + +void ms_inoti_remove_watch_recursive(char *path); + +void ms_inoti_remove_watch(char *path); + +void ms_inoti_modify_watch(char *path_from, char *path_to); + +int ms_inoti_add_ignore_file(const char *path); + +int ms_inoti_delete_ignore_file(ms_ignore_file_info * delete_node); + +ms_ignore_file_info *ms_inoti_find_ignore_file(const char *path); + +void ms_inoti_delete_mmc_ignore_file(void); +#endif /* _FEXPLORER_ENGINE_INOTI_H_ */ diff --git a/common/include/media-server-scan-internal.h b/common/include/media-server-scan-internal.h new file mode 100755 index 0000000..7837792 --- /dev/null +++ b/common/include/media-server-scan-internal.h @@ -0,0 +1,38 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-scan-internal.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include "media-server-global.h" +#include "media-server-types.h" + +#ifdef PROGRESS +struct quickpanel; +void _ms_dir_scan(ms_scan_data_t * scan_data, struct quickpanel *ms_quickpanel); +#else +void _ms_dir_scan(ms_scan_data_t * scan_data); +#endif diff --git a/common/include/media-server-scan.h b/common/include/media-server-scan.h new file mode 100755 index 0000000..1cea90b --- /dev/null +++ b/common/include/media-server-scan.h @@ -0,0 +1,31 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-scan.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +gboolean ms_scan_thread(void *data); diff --git a/common/include/media-server-socket.h b/common/include/media-server-socket.h new file mode 100755 index 0000000..934c0bd --- /dev/null +++ b/common/include/media-server-socket.h @@ -0,0 +1,34 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-thumb.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + #include "media-server-global.h" +#include "media-server-types.h" + +gboolean ms_socket_thread(void *data); + diff --git a/common/include/media-server-thumb.h b/common/include/media-server-thumb.h new file mode 100755 index 0000000..064c0f9 --- /dev/null +++ b/common/include/media-server-thumb.h @@ -0,0 +1,35 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-thumb.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include "media-server-global.h" +#include "media-server-types.h" + +#ifdef THUMB_THREAD +gboolean ms_thumb_thread(void *data); +#endif diff --git a/common/include/media-server-types.h b/common/include/media-server-types.h new file mode 100755 index 0000000..da63a7c --- /dev/null +++ b/common/include/media-server-types.h @@ -0,0 +1,99 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-types.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#include <stdbool.h> +#include <glib.h> + +#ifndef _FEXPLORER_TYPES_H_ +#define _FEXPLORER_TYPES_H_ + +#if !defined(__TYPEDEF_INT64__) +#define __TYPEDEF_INT64__ +typedef long long int64; +#endif + +/*System default folder definition*/ +#define FAT_FILENAME_LEN_MAX 255 /* not inc null */ +#define FAT_FILEPATH_LEN_MAX 4096 /* inc null */ +#define FAT_DIRECTORY_LEN_MAX 244 + +/* The following MACROs(TAF_XXX) are defined in "fs-limit.h"*/ +#define MS_FILE_NAME_LEN_MAX FAT_FILENAME_LEN_MAX /**< File name max length on file system */ +#define MS_FILE_PATH_LEN_MAX FAT_FILEPATH_LEN_MAX /**< File path max length (include file name) on file system */ + +#define MS_CATEGORY_UNKNOWN 0x00000000 /**< Default */ +#define MS_CATEGORY_ETC 0x00000001 /**< ETC category */ +#define MS_CATEGORY_IMAGE 0x00000002 /**< Image category */ +#define MS_CATEGORY_VIDEO 0x00000004 /**< Video category */ +#define MS_CATEGORY_MUSIC 0x00000008 /**< Music category */ +#define MS_CATEGORY_SOUND 0x00000010 /**< Sound category */ +#define MS_CATEGORY_DRM 0x00000020 /**< DRM category */ + +typedef enum { + MS_PHONE, /**< Stored only in phone */ + MS_MMC, /**< Stored only in MMC */ +} ms_store_type_t; + +typedef enum { + MS_SCAN_NONE, + MS_SCAN_VALID, + MS_SCAN_PART, + MS_SCAN_ALL, +} ms_dir_scan_type_t; + +typedef enum { + MS_DB_UPDATING = 0, + MS_DB_UPDATED = 1 +} ms_db_status_type_t; + +typedef struct ms_dir_scan_info { + char *name; + struct ms_dir_scan_info *parent; + struct ms_dir_scan_info *Rbrother; + struct ms_dir_scan_info *next; +} ms_dir_scan_info; + +typedef struct { + ms_store_type_t db_type; + ms_dir_scan_type_t scan_type; +} ms_scan_data_t; + +typedef struct ms_dir_data { + char *name; + int wd; + bool db_updated; + struct ms_dir_data *next; +} ms_dir_data; + +/** + * @} + */ + +#endif /*_FEXPLORER_TYPES_H_*/ diff --git a/common/media-server-common.c b/common/media-server-common.c new file mode 100755 index 0000000..3f007cd --- /dev/null +++ b/common/media-server-common.c @@ -0,0 +1,1780 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-common.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief This file implements main database operation. + */ +#include <media-svc.h> +#include <media-thumbnail.h> +#include <audio-svc-error.h> +#include <audio-svc.h> +#include <db-util.h> +#include <pmapi.h> +#include <vconf.h> +#include <drm-service.h> +#ifdef PROGRESS +#include <quickpanel.h> +#endif +#include <aul/aul.h> +#include <mmf/mm_file.h> + +#include "media-server-global.h" +#include "media-server-common.h" +#include "media-server-inotify.h" + +#ifdef FMS_PERF +#include <sys/time.h> +#define MILLION 1000000L +#endif + +#define CONTENT_TYPE_NUM 4 +#define MUSIC_MIME_NUM 28 +#define SOUND_MIME_NUM 1 +#define MIME_TYPE_LENGTH 255 +#define MIME_LENGTH 50 +#define _3GP_FILE ".3gp" +#define _MP4_FILE ".mp4" +#define MMC_INFO_SIZE 256 + +int mmc_state = 0; +int ums_mode = 0; +int current_usb_mode = 0; + +extern GAsyncQueue *scan_queue; + +struct timeval g_mmc_start_time; +struct timeval g_mmc_end_time; + +typedef struct { + char content_type[15]; + int category_by_mime; +} fex_content_table_t; + +static const fex_content_table_t content_category[CONTENT_TYPE_NUM] = { + {"audio", MS_CATEGORY_SOUND}, + {"image", MS_CATEGORY_IMAGE}, + {"video", MS_CATEGORY_VIDEO}, + {"application", MS_CATEGORY_ETC}, +}; + +static const char music_mime_table[MUSIC_MIME_NUM][MIME_LENGTH] = { + /*known mime types of normal files*/ + "mpeg", + "ogg", + "x-ms-wma", + "x-flac", + "mp4", + /* known mime types of drm files*/ + "mp3", + "x-mp3", /*alias of audio/mpeg*/ + "x-mpeg", /*alias of audio/mpeg*/ + "3gpp", + "x-ogg", /*alias of audio/ogg*/ + "vnd.ms-playready.media.pya:*.pya", /*playready*/ + "wma", + "aac", + "x-m4a", /*alias of audio/mp4*/ + /* below mimes are rare*/ + "x-vorbis+ogg", + "x-flac+ogg", + "x-matroska", + "ac3", + "mp2", + "x-ape", + "x-ms-asx", + "vnd.rn-realaudio", + + "x-vorbis", /*alias of audio/x-vorbis+ogg*/ + "vorbis", /*alias of audio/x-vorbis+ogg*/ + "x-oggflac", + "x-mp2", /*alias of audio/mp2*/ + "x-pn-realaudio", /*alias of audio/vnd.rn-realaudio*/ + "vnd.m-realaudio", /*alias of audio/vnd.rn-realaudio*/ +}; + +static const char sound_mime_table[SOUND_MIME_NUM][MIME_LENGTH] = { + "x-smaf", +}; + +int ms_update_valid_type(char *path) +{ + MS_DBG_START(); + + int res = MS_ERR_NONE; + int err; + int category = MS_CATEGORY_UNKNOWN; + + MS_DBG("%s", path); + + err = ms_get_category_from_mime(path, &category); + if (err < 0) { + MS_DBG("ms_get_category_from_mime fails"); + return err; + } + + /*if music, call mp_svc_set_item_valid() */ + if (category & MS_CATEGORY_MUSIC || category & MS_CATEGORY_SOUND) { + /*check exist in Music DB, If file is not exist, insert data in DB. */ + err = audio_svc_check_item_exist(path); + if (err == AUDIO_SVC_ERROR_DB_NO_RECORD) { + MS_DBG("not exist in Music DB. insert data"); +#ifdef THUMB_THREAD + err = ms_media_db_insert_with_thumb(path, category); +#else + err = ms_media_db_insert(path, category, true); +#endif + if (err != MS_ERR_NONE) { + MS_DBG ("ms_media_db_insert() error %d", err); + res = err; + } + } + else if (err == AUDIO_SVC_ERROR_NONE) { + /*if meta data of file exist, change valid field to "1" */ + MS_DBG("Item exist"); + + err = audio_svc_set_item_valid(path, true); + if (err != AUDIO_SVC_ERROR_NONE) + MS_DBG("audio_svc_set_item_valid() error : %d", err); + } + else + { + MS_DBG("audio_svc_check_item_exist() error : %d", err); + res = MS_ERR_DB_OPERATION_FAIL; + } + } + /*if file is image file, call mb_svc_set_db_item_valid() */ + else if (category & MS_CATEGORY_VIDEO || category & MS_CATEGORY_IMAGE) { + ms_store_type_t store_type; + minfo_store_type mb_stroage; + + store_type = ms_get_store_type_by_full(path); + mb_stroage = (store_type == MS_MMC) ? MINFO_MMC : MINFO_PHONE; + + err = minfo_set_item_valid(mb_stroage, path, true); + if (err != MB_SVC_ERROR_NONE) { + MS_DBG("not exist in Media DB. insert data"); + + ms_update_valid_type_end(); + +#ifdef THUMB_THREAD + err = ms_media_db_insert_with_thumb(path, category); +#else + err = ms_media_db_insert(path, category, true); +#endif + if (err != MS_ERR_NONE) + MS_DBG("ms_media_db_insert() error : %d", err); + + ms_update_valid_type_start(); + } + else { + MS_DBG("Item exist"); + } + } + + if (category & MS_CATEGORY_DRM) { + DRM_RESULT drm_res; + + ms_inoti_add_ignore_file(path); + drm_res = drm_svc_register_file(path); + if (drm_res != DRM_RESULT_SUCCESS) { + MS_DBG("drm_svc_register_file error : %d", drm_res); + res = MS_ERR_DRM_REGISTER_FAIL; + } + } + + MS_DBG_END(); + + return res; +} + +static int _ms_set_power_mode(ms_db_status_type_t status) +{ + int res = MS_ERR_NONE; + int err; + + switch (status) { + case MS_DB_UPDATING: + err = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0); + if (err != 0) + res = MS_ERR_UNKNOWN_ERROR; + break; + case MS_DB_UPDATED: + err = pm_unlock_state(LCD_OFF, STAY_CUR_STATE); + if (err != 0) + res = MS_ERR_UNKNOWN_ERROR; + break; + default: + MS_DBG("Unacceptable type : %d", status); + break; + } + + return res; +} + +int ms_set_db_status(ms_db_status_type_t status) +{ + int res = MS_ERR_NONE; + int err = 0; + + if (status == MS_DB_UPDATING) { + if (ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) + res = MS_ERR_VCONF_SET_FAIL; + } else if (status == MS_DB_UPDATED) { + if(ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED)) + res = MS_ERR_VCONF_SET_FAIL; + } + + err = _ms_set_power_mode(status); + if (err != MS_ERR_NONE) { + MS_DBG("_ms_set_power_mode fail"); + res = err; + } + + return res; +} + +GMutex * db_mutex; + +int ms_db_init(bool need_db_create) +{ + MS_DBG_START(); + + ms_scan_data_t *phone_scan_data; + ms_scan_data_t *mmc_scan_data; + + phone_scan_data = malloc(sizeof(ms_scan_data_t)); + mmc_scan_data = malloc(sizeof(ms_scan_data_t)); + MS_DBG("*********************************************************"); + MS_DBG("*** Begin to check tables of file manager in database ***"); + MS_DBG("*********************************************************"); + + fex_make_default_path(); + + phone_scan_data->db_type = MS_PHONE; + + if (need_db_create) { + /*insert records */ + MS_DBG("Create DB"); + + phone_scan_data->scan_type = MS_SCAN_ALL; + } else { + MS_DBG("JUST ADD WATCH"); + phone_scan_data->scan_type = MS_SCAN_NONE; + } + + /*push data to fex_dir_scan_cb */ + g_async_queue_push(scan_queue, GINT_TO_POINTER(phone_scan_data)); + + if (ms_is_mmc_supported()) { + mmc_state = VCONFKEY_SYSMAN_MMC_MOUNTED; + +#ifdef _WITH_DRM_SERVICE_ + if (drm_svc_insert_ext_memory() == DRM_RESULT_SUCCESS) + MS_DBG + ("fex_db_service_init : drm_svc_insert_ext_memory OK"); +#endif + + fex_make_default_path_mmc(); + + mmc_scan_data->scan_type = ms_get_mmc_state(); + mmc_scan_data->db_type = MS_MMC; + + MS_DBG("ms_get_mmc_state is %d", mmc_scan_data->scan_type); + + g_async_queue_push(scan_queue, GINT_TO_POINTER(mmc_scan_data)); + } + + MS_DBG_END(); + return 0; +} + +int ms_media_db_open(void) +{ + int err; + + /*Lock mutex for openning db*/ + g_mutex_lock(db_mutex); + + err = minfo_init(); + if (err != MB_SVC_ERROR_NONE) { + MS_DBG("minfo_init() error : %d", err); + + g_mutex_unlock(db_mutex); + + return MS_ERR_DB_CONNECT_FAIL; + } + + err = audio_svc_open(); + if (err != AUDIO_SVC_ERROR_NONE) { + MS_DBG("audio_svc_open() error : %d", err); + err = minfo_finalize(); + if (err != MB_SVC_ERROR_NONE) + MS_DBG("minfo_finalize() error: %d", err); + + g_mutex_unlock(db_mutex); + + return MS_ERR_DB_CONNECT_FAIL; + } + MS_DBG("connect Media DB"); + + g_mutex_unlock(db_mutex); + + return MS_ERR_NONE; +} + +int ms_media_db_close(void) +{ + int err; + + err = audio_svc_close(); + if (err != AUDIO_SVC_ERROR_NONE) { + MS_DBG("audio_svc_close() error : %d", err); + return MS_ERR_DB_DISCONNECT_FAIL; + } + + err = minfo_finalize(); + if (err != MB_SVC_ERROR_NONE) { + MS_DBG("minfo_finalize() error: %d", err); + return MS_ERR_DB_DISCONNECT_FAIL; + } + + MS_DBG("Disconnect Media DB"); + + return MS_ERR_NONE; +} + +int +_ms_update_mmc_info(const char *cid) +{ + MS_DBG_START(); + bool res; + + if (cid == NULL) { + MS_DBG("Parameters are invalid"); + return MS_ERR_ARG_INVALID; + } + + res = ms_config_set_str(MS_MMC_INFO_KEY, cid); + if (!res) { + MS_DBG("fail to get MS_MMC_INFO_KEY"); + return MS_ERR_VCONF_SET_FAIL; + } + + MS_DBG_END(); + + return MS_ERR_NONE; +} + +bool +_ms_check_mmc_info(const char *cid) +{ + MS_DBG_START(); + + char pre_mmc_info[MMC_INFO_SIZE] = { 0 }; + bool res = false; + + if (cid == NULL) { + MS_DBG("Parameters are invalid"); + return false; + } + + res = ms_config_get_str(MS_MMC_INFO_KEY, pre_mmc_info); + if (!res) { + MS_DBG("fail to get MS_MMC_INFO_KEY"); + return false; + } + + MS_DBG("Last MMC info = %s", pre_mmc_info); + MS_DBG("Current MMC info = %s", cid); + + if (strcmp(pre_mmc_info, cid) == 0) { + return true; + } + + MS_DBG_END(); + return false; +} + +static int _get_contents(const char *filename, char *buf) +{ + FILE *fp; + + MS_DBG("%s", filename); + + fp = fopen(filename, "rt"); + if (fp == NULL) { + MS_DBG("fp is NULL"); + return MS_ERR_FILE_OPEN_FAIL; + } + fgets(buf, 255, fp); + + fclose(fp); + + return MS_ERR_NONE; +} + +/*need optimize*/ +int _ms_get_mmc_info(char *cid) +{ + MS_DBG_START(); + + int i; + int j; + int len; + int err = -1; + bool getdata = false; + bool bHasColon = false; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + char mmcpath[MS_FILE_PATH_LEN_MAX] = { 0 }; + + DIR *dp; + struct dirent ent; + struct dirent *res = NULL; + + /* mmcblk0 and mmcblk1 is reserved for movinand */ + for (j = 1; j < 3; j++) { + len = snprintf(mmcpath, MS_FILE_PATH_LEN_MAX, "/sys/class/mmc_host/mmc%d/", j); + if (len < 0) { + MS_DBG("FAIL : snprintf"); + return MS_ERR_UNKNOWN_ERROR; + } + else { + mmcpath[len] = '\0'; + } + + dp = opendir(mmcpath); + + if (dp == NULL) { + MS_DBG("dp is NULL"); + { + return MS_ERR_DIR_OPEN_FAIL; + } + } + + while (!readdir_r(dp, &ent, &res)) { + /*end of read dir*/ + if (res == NULL) + break; + + bHasColon = false; + if (ent.d_name[0] == '.') + continue; + + if (ent.d_type == DT_DIR) { + /*ent->d_name is including ':' */ + for (i = 0; i < strlen(ent.d_name); i++) { + if (ent.d_name[i] == ':') { + bHasColon = true; + break; + } + } + + if (bHasColon) { + /*check serial */ + err = ms_strappend(path, sizeof(path), "%s%s/cid", mmcpath, ent.d_name); + if (err < 0) { + MS_DBG("FAIL : ms_strappend"); + continue; + } + + if (_get_contents(path, cid) != MS_ERR_NONE) + break; + else + getdata = true; + MS_DBG("MMC serial : %s", cid); + } + } + } + closedir(dp); + + if (getdata == true) { + break; + } + } + + MS_DBG_END(); + + return MS_ERR_NONE; +} + +int ms_update_mmc_info(void) +{ + int err; + char cid[MMC_INFO_SIZE] = { 0 }; + + err = _ms_get_mmc_info(cid); + + err = _ms_update_mmc_info(cid); + + /*Active flush */ + if (malloc_trim(0)) + MS_DBG("SUCCESS malloc_trim"); + + return err; +} + +void ms_mmc_removed_handler(void) +{ + ms_scan_data_t *mmc_scan_data; + + mmc_scan_data = malloc(sizeof(ms_scan_data_t)); + + mmc_scan_data->scan_type = MS_SCAN_VALID; + mmc_scan_data->db_type = MS_MMC; + + g_async_queue_push(scan_queue, GINT_TO_POINTER(mmc_scan_data)); + + /*remove added watch descriptors */ + ms_inoti_remove_watch_recursive(MS_MMC_ROOT_PATH); + + ms_inoti_delete_mmc_ignore_file(); + + if (drm_svc_extract_ext_memory() == DRM_RESULT_SUCCESS) + MS_DBG("drm_svc_extract_ext_memory OK"); +} + +void ms_mmc_vconf_cb(void *data) +{ + MS_DBG_START(); + + int status = 0; + ms_scan_data_t *scan_data; + + MS_DBG("Received MMC noti from vconf : %d", status); + + if (!ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) { + MS_DBG("........Get VCONFKEY_SYSMAN_MMC_STATUS failed........"); + } + + MS_DBG("ms_config_get_int : VCONFKEY_SYSMAN_MMC_STATUS END = %d", + status); + + mmc_state = status; + + if (current_usb_mode != VCONFKEY_USB_STORAGE_STATUS_OFF) + return; + + if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED || + mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) { + ms_mmc_removed_handler(); + } + else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { + scan_data = malloc(sizeof(ms_scan_data_t)); +#ifdef _WITH_DRM_SERVICE_ + if (drm_svc_insert_ext_memory() == DRM_RESULT_SUCCESS) + MS_DBG("drm_svc_insert_ext_memory OK"); +#endif + fex_make_default_path_mmc(); + + scan_data->scan_type = ms_get_mmc_state(); + scan_data->db_type = MS_MMC; + + MS_DBG("ms_get_mmc_state is %d", scan_data->scan_type); + + g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); + } + + MS_DBG_END(); + + return; +} + +#ifdef FMS_PERF + +void ms_check_start_time(struct timeval *start_time) +{ + gettimeofday(start_time, NULL); +} + +void ms_check_end_time(struct timeval *end_time) +{ + gettimeofday(end_time, NULL); +} + +void ms_check_time_diff(struct timeval *start_time, struct timeval *end_time) +{ + struct timeval time; + long difftime; + + time.tv_sec = end_time->tv_sec - start_time->tv_sec; + time.tv_usec = end_time->tv_usec - start_time->tv_usec; + difftime = MILLION * time.tv_sec + time.tv_usec; + MS_DBG("The function_to_time took %ld microseconds or %f seconds.", + difftime, difftime / (double)MILLION); +} + +#endif + +void ms_usb_vconf_cb(void *data) +{ + MS_DBG_START(); + + int status = 0; + + MS_DBG("Received usb noti from vconf : %d", status); + + if (!ms_config_get_int(VCONFKEY_USB_STORAGE_STATUS, &status)) { + MS_DBG + ("........Get VCONFKEY_USB_STORAGE_STATUS failed........"); + } + + MS_DBG("ms_config_get_int : VCONFKEY_USB_STORAGE_STATUS END = %d", + status); + current_usb_mode = status; + + if (current_usb_mode == VCONFKEY_USB_STORAGE_STATUS_OFF) { + if (ums_mode != VCONFKEY_USB_STORAGE_STATUS_OFF) { + ms_scan_data_t *int_scan; + + fex_make_default_path(); + + int_scan = malloc(sizeof(ms_scan_data_t)); + + int_scan->db_type = MS_PHONE; + int_scan->scan_type = MS_SCAN_PART; + + /*push data to fex_dir_scan_cb */ + g_async_queue_push(scan_queue, GINT_TO_POINTER(int_scan)); + + if (ms_is_mmc_supported()) { + ms_scan_data_t *ext_scan; + + /*prepare to insert drm data and delete previous drm datas */ + if (drm_svc_insert_ext_memory() == + DRM_RESULT_SUCCESS) + MS_DBG("drm_svc_insert_ext_memory OK"); + + ext_scan = malloc(sizeof(ms_scan_data_t)); + mmc_state = VCONFKEY_SYSMAN_MMC_MOUNTED; + + ext_scan->db_type = MS_MMC; + ext_scan->scan_type = MS_SCAN_PART; + + /*push data to fex_dir_scan_cb */ + g_async_queue_push(scan_queue, GINT_TO_POINTER(ext_scan)); + } + } + ums_mode = VCONFKEY_USB_STORAGE_STATUS_OFF; + ms_config_set_int(MS_USB_MODE_KEY, MS_VCONFKEY_NORMAL_MODE); + } + else { + if (ums_mode == VCONFKEY_USB_STORAGE_STATUS_OFF) { + MS_DBG("VCONFKEY_USB_STORAGE_STATUS : %d", current_usb_mode); + ms_scan_data_t *int_scan; + + ums_mode = current_usb_mode; + + int_scan = malloc(sizeof(ms_scan_data_t)); + int_scan->scan_type = MS_SCAN_VALID; + int_scan->db_type = MS_PHONE; + + g_async_queue_push(scan_queue, GINT_TO_POINTER(int_scan)); + + ms_inoti_remove_watch_recursive(MS_PHONE_ROOT_PATH); + + if (ums_mode == VCONFKEY_USB_STORAGE_STATUS_UMS_MMC_ON) { + + ms_scan_data_t *ext_scan; + + ext_scan = malloc(sizeof(ms_scan_data_t)); + ext_scan->scan_type = MS_SCAN_VALID; + ext_scan->db_type = MS_MMC; + + g_async_queue_push(scan_queue, GINT_TO_POINTER(ext_scan)); + + ms_inoti_remove_watch_recursive(MS_MMC_ROOT_PATH); + + /*notify to drm-server */ + if (drm_svc_extract_ext_memory() == DRM_RESULT_SUCCESS) + MS_DBG("drm_svc_extract_ext_memory OK"); + } + + /*delete all drm contect from drm server */ + if (drm_svc_unregister_all_contents() == DRM_RESULT_SUCCESS) + MS_DBG("drm_svc_unregister_all_contents OK"); + + ms_config_set_int(MS_USB_MODE_KEY, MS_VCONFKEY_MASS_STORAGE_MODE); + } + } + + MS_DBG_END(); + return; +} + +bool ms_is_mmc_supported(void) +{ + MS_DBG_START(); + + /*TODO-Q: simulator support? */ + if (0) + /* if (strcmp(FEXPLORER_MMC_ROOT_PATH, "/mnt/mmc") == 0) //simulator */ + { + return true; + } else { + int data = -1; + ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &data); + MS_DBG("%s is %d ", VCONFKEY_SYSMAN_MMC_STATUS, data); + if (data != VCONFKEY_SYSMAN_MMC_MOUNTED) + return false; + else + return true; + } + + MS_DBG_END(); + return false; +} + +ms_dir_scan_type_t ms_get_mmc_state(void) +{ + char cid[MMC_INFO_SIZE] = { 0 }; + ms_dir_scan_type_t ret = MS_SCAN_ALL; + + /*get new info */ + _ms_get_mmc_info(cid); + + /*check it's same mmc */ + if (_ms_check_mmc_info(cid)) { + MS_DBG("Detected same MMC! but needs to update the changes..."); + ret = MS_SCAN_PART; + } + + return ret; +} + +GAsyncQueue* soc_queue; +GArray *reg_list; +GMutex *list_mutex; +GMutex *queue_mutex; + +void _ms_insert_reg_list(const char *path) +{ + char *reg_path = strdup(path); + + g_mutex_lock(list_mutex); + + g_array_append_val(reg_list, reg_path); + + g_mutex_unlock(list_mutex); +} + +bool _ms_find_reg_list(const char *path) +{ + int i; + int len = reg_list->len; + char *data; + bool ret = false; + + g_mutex_lock(list_mutex); + MS_DBG("array length : %d", len); + + for(i = 0; i < len; i++) { + data = g_array_index (reg_list, char*, i); + if(!strcmp(data, path)) + ret = true; + } + + g_mutex_unlock(list_mutex); + + return ret; +} + +void _ms_delete_reg_list(const char *path) +{ + int i; + int len = reg_list->len; + char *data; + + MS_DBG("Delete : %s", path); + g_mutex_lock(list_mutex); + + for(i = 0; i < len; i++) { + data = g_array_index (reg_list, char*, i); + MS_DBG("%s", data); + if(!strcmp(data, path)) { + MS_DBG("Delete complete : %s", data); + free(data); + g_array_remove_index(reg_list, i); + break; + } + } + + g_mutex_unlock(list_mutex); +} + +void ms_register_start(void) +{ + minfo_add_media_start(MS_REGISTER_COUNT); + audio_svc_insert_item_start(MS_REGISTER_COUNT); +} + +void ms_register_end(void) +{ + minfo_add_media_end(); + audio_svc_insert_item_end(); +} + +int ms_register_file(const char *path, GAsyncQueue* queue) +{ + MS_DBG_START(); + MS_DBG("[%d]register file : %s", syscall(__NR_gettid), path); + + int err; + int category = MS_CATEGORY_UNKNOWN; + + if (path == NULL) { + MS_DBG("path == NULL"); + return MS_ERR_ARG_INVALID; + } + + g_mutex_lock(queue_mutex); + /*first request for this file*/ + if(!_ms_find_reg_list(path)) { + /*insert registering file list*/ + _ms_insert_reg_list(path); + } else { + MS_DBG("______________________ALREADY INSERTING"); + if(queue != NULL) { + MS_DBG("Need reply"); + soc_queue = queue; + } + g_mutex_unlock(queue_mutex); + return MS_ERR_NOW_REGISTER_FILE; + } + g_mutex_unlock(queue_mutex); + + err = ms_get_category_from_mime(path, &category); + if (err != MS_ERR_NONE) { + MS_DBG("ms_get_category_from_mime error : %d", err); + goto FREE_RESOURCE; + } + + if (category <= MS_CATEGORY_ETC) { + MS_DBG("This is not media contents"); + err = MS_ERR_NOT_MEDIA_FILE; + goto FREE_RESOURCE; + } else { +#ifdef THUMB_THREAD + err = ms_media_db_insert_with_thumb(path, category); +#else + err = ms_media_db_insert(path, category, false); +#endif + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_insert error : %d", err); + + /*if music, call mp_svc_set_item_valid() */ + if (category & MS_CATEGORY_MUSIC || category & MS_CATEGORY_SOUND) { + /*check exist in Music DB, If file is not exist, insert data in DB. */ + err = audio_svc_check_item_exist(path); + if (err == AUDIO_SVC_ERROR_NONE) { + MS_DBG("Audio Item exist"); + err = MS_ERR_NONE; + } + } else if (category & MS_CATEGORY_VIDEO || category & MS_CATEGORY_IMAGE) { + Mitem *mi = NULL; + + /*get an item based on its url. */ + err = minfo_get_item(path, &mi); + if (err == MB_SVC_ERROR_NONE) { + MS_DBG("Visual Item exist"); + err = MS_ERR_NONE; + } + + minfo_destroy_mtype_item(mi); + } + } + + if (category & MS_CATEGORY_DRM) { + MS_DBG("THIS IS DRM FILE"); + DRM_RESULT res; + + ms_inoti_add_ignore_file(path); + res = drm_svc_register_file(path); + if (res != DRM_RESULT_SUCCESS) { + MS_DBG("drm_svc_register_file error : %d", res); + err = MS_ERR_DRM_REGISTER_FAIL; + } + } + } + +FREE_RESOURCE: + g_mutex_lock(queue_mutex); + + _ms_delete_reg_list(path); + + if (soc_queue != NULL) { + MS_DBG("%d", err); + g_async_queue_push(soc_queue, GINT_TO_POINTER(err+MS_ERR_MAX)); + MS_DBG("Return OK"); + } + soc_queue = NULL; + g_mutex_unlock(queue_mutex); + MS_DBG_END(); + return err; +} + +int ms_register_scanfile(const char *path) +{ + MS_DBG_START(); + MS_DBG("register scanfile : %s", path); + + int err = MS_ERR_NONE; + bool res = false; + int category = MS_CATEGORY_UNKNOWN; + + if (path == NULL) { + MS_DBG("path == NULL"); + return MS_ERR_ARG_INVALID; + } + + err = ms_get_category_from_mime(path, &category); + if (err != MS_ERR_NONE) { + MS_DBG("ms_get_category_from_mime error : %d", err); + return err; + } + + if (category <= MS_CATEGORY_ETC) { + MS_DBG("This is not media contents"); + return MS_ERR_NOT_MEDIA_FILE; + } + + err = ms_media_db_insert(path, category, true); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_insert error : %d", err); + } + + if (category & MS_CATEGORY_DRM) { + MS_DBG("THIS IS DRM FILE"); + DRM_RESULT res; + + ms_inoti_add_ignore_file(path); + + res = drm_svc_register_file(path); + if (res != DRM_RESULT_SUCCESS) { + MS_DBG("drm_svc_register_file error : %d", err); + err = MS_ERR_DRM_REGISTER_FAIL; + } + } + + MS_DBG_END(); + return err; +} + + +int ms_start(bool need_db_create) +{ + int err = 0; + + err = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + (vconf_callback_fn) ms_mmc_vconf_cb, NULL); + if (err == -1) + MS_DBG("add call back function for event %s fails", + VCONFKEY_SYSMAN_MMC_STATUS); + + err = vconf_notify_key_changed(VCONFKEY_USB_STORAGE_STATUS, + (vconf_callback_fn) ms_usb_vconf_cb, NULL); + if (err == -1) + MS_DBG("add call back function for event %s fails", + VCONFKEY_USB_STORAGE_STATUS); + + ms_db_init(need_db_create); + + malloc_trim(0); + + return err; +} + +void ms_end(void) +{ + /*********** + **remove call back functions + ************/ + vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + (vconf_callback_fn) ms_mmc_vconf_cb); + vconf_ignore_key_changed(VCONFKEY_USB_STORAGE_STATUS, + (vconf_callback_fn) ms_usb_vconf_cb); + + /*Clear db mutex variable*/ + g_mutex_free (db_mutex); +} + +int ms_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path) +{ + int err = 0; + ms_dir_scan_info *cur_node; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + char tmp_path[MS_FILE_PATH_LEN_MAX] = { 0 }; + + cur_node = node; + MS_DBG("%s", cur_node->name); + + while (1) { + err = ms_strappend(path, sizeof(path), "/%s%s", cur_node->name, tmp_path); + if (err < 0) { + MS_DBG("ms_strappend error : %d", err); + return err; + } + + strncpy(tmp_path, path, MS_FILE_PATH_LEN_MAX); + + if (cur_node->parent == NULL) + break; + + cur_node = cur_node->parent; + memset(path, 0, MS_FILE_PATH_LEN_MAX); + } + + strncpy(ret_path, path, MS_FILE_PATH_LEN_MAX); + + return err; +} + +ms_store_type_t ms_get_store_type_by_full(const char *path) +{ + if (strncmp(path + 1, MS_PHONE_ROOT_PATH, strlen(MS_PHONE_ROOT_PATH)) == 0) { + return MS_PHONE; + } else + if (strncmp(path + 1, MS_MMC_ROOT_PATH, strlen(MS_MMC_ROOT_PATH)) == 0) { + return MS_MMC; + } else + return MS_ERR_INVALID_FILE_PATH; +} + +int +ms_strappend(char *res, const int size, const char *pattern, + const char *str1, const char *str2) +{ + int len = 0; + int real_size = size - 1; + + if (!res ||!pattern || !str1 ||!str2 ) + return MS_ERR_ARG_INVALID; + + if (real_size < (strlen(str1) + strlen(str2))) + return MS_ERR_OUT_OF_RANGE; + + len = snprintf(res, real_size, pattern, str1, str2); + if (len < 0) { + MS_DBG("MS_ERR_ARG_INVALID"); + return MS_ERR_ARG_INVALID; + } + + res[len] = '\0'; + + return MS_ERR_NONE; +} + +int +ms_strcopy(char *res, const int size, const char *pattern, const char *str1) +{ + int len = 0; + int real_size = size - 1; + + if (!res || !pattern || !str1) + return MS_ERR_ARG_INVALID; + + if (real_size < strlen(str1)) + return MS_ERR_OUT_OF_RANGE; + + len = snprintf(res, real_size, pattern, str1); + if (len < 0) { + MS_DBG("MS_ERR_ARG_INVALID"); + return MS_ERR_ARG_INVALID; + } + + res[len] = '\0'; + + return MS_ERR_NONE; +} + +#ifdef _WITH_SETTING_AND_NOTI_ +bool ms_config_get_int(const char *key, int *value) +{ + int err; + + if (!key || !value) { + MS_DBG("Arguments key or value is NULL"); + return false; + } + + err = vconf_get_int(key, value); + if (err == 0) + return true; + else if (err == -1) + return false; + else + MS_DBG("Unexpected error code: %d", err); + + return false; +} + +bool ms_config_set_int(const char *key, int value) +{ + int err; + + if (!key) { + MS_DBG("Arguments key is NULL"); + return false; + } + + err = vconf_set_int(key, value); + if (err == 0) + return true; + else if (err == -1) + return false; + else + MS_DBG("Unexpected error code: %d", err); + + return false; +} + +bool ms_config_get_str(const char *key, char *value) +{ + char *res; + if (!key || !value) { + MS_DBG("Arguments key or value is NULL"); + return false; + } + + res = vconf_get_str(key); + if (res) { + strncpy(value, res, strlen(res) + 1); + return true; + } + + return false; +} + +bool ms_config_set_str(const char *key, const char *value) +{ + int err; + + if (!key || !value) { + MS_DBG("Arguments key or value is NULL"); + return false; + } + + err = vconf_set_str(key, value); + if (err == 0) + return true; + else + MS_DBG("fail to vconf_set_str %d", err); + + return false; +} +#endif /* _WITH_SETTING_AND_NOTI_ */ + +bool fex_make_default_path(void) +{ + int i = 0; + int ret = 0; + bool create_flag = false; + DIR *dp = NULL; + + char default_path[10][256] = { + {"/opt/media/Images and videos"}, + {"/opt/media/Images and videos/Wallpapers"}, + {"/opt/media/Sounds and music"}, + {"/opt/media/Sounds and music/Music"}, + {"/opt/media/Sounds and music/Ringtones"}, + {"/opt/media/Sounds and music/Alerts"}, + {"/opt/media/Sounds and music/FM Radio"}, + {"/opt/media/Sounds and music/Voice recorder"}, + {"/opt/media/Downloads"}, + {"/opt/media/Camera shots"} + }; + + for (i = 0; i < 10; ++i) { + dp = opendir(default_path[i]); + if (dp == NULL) { + ret = mkdir(default_path[i], 0777); + if (ret < 0) { + MS_DBG("make fail"); + } else { + create_flag = true; + ms_inoti_add_watch(default_path[i]); + } + } else { + closedir(dp); + } + } + + return create_flag; +} + +bool fex_make_default_path_mmc(void) +{ + MS_DBG_START(); + + int i = 0; + int ret = 0; + bool create_flag = false; + DIR *dp = NULL; + + char default_path[10][256] = { + {"/opt/storage/sdcard/Images and videos"}, + {"/opt/storage/sdcard/Images and videos/Wallpapers"}, + {"/opt/storage/sdcard/Sounds and music"}, + {"/opt/storage/sdcard/Sounds and music/Music"}, + {"/opt/storage/sdcard/Sounds and music/Ringtones"}, + {"/opt/storage/sdcard/Sounds and music/Alerts"}, + {"/opt/storage/sdcard/Sounds and music/FM Radio"}, + {"/opt/storage/sdcard/Sounds and music/Voice recorder"}, + {"/opt/storage/sdcard/Downloads"}, + {"/opt/storage/sdcard/Camera shots"} + }; + + for (i = 0; i < 10; ++i) { + dp = opendir(default_path[i]); + if (dp == NULL) { + ret = mkdir(default_path[i], 0777); + if (ret < 0) { + MS_DBG("make fail"); + } else { + create_flag = true; + ms_inoti_add_watch(default_path[i]); + } + } else { + closedir(dp); + } + } + + MS_DBG_END(); + + return create_flag; +} + +static int _ms_get_mime_by_drm_info(const char *path, char *mime) +{ +#ifdef _WITH_DRM_SERVICE_ + int res = MS_ERR_NONE; + drm_content_info_t contentInfo = { 0 }; + + if (path == NULL || mime == NULL) + return MS_ERR_ARG_INVALID; + + res = drm_svc_get_content_info(path, &contentInfo); + if (res != DRM_RESULT_SUCCESS) { + MS_DBG("drm_svc_get_content_info() fails. "); + return res; + } + + strncpy(mime, contentInfo.contentType, MS_DRM_CONTENT_TYPE_LENGTH); + + return res; +#else + return MS_ERR_NONE; +#endif +} + +int ms_get_category_from_mime(const char *path, int *category) +{ + int i = 0; + int err = 0; + char mimetype[MIME_TYPE_LENGTH]; + + if (path == NULL || category == NULL) + return MS_ERR_ARG_INVALID; + + *category = MS_CATEGORY_UNKNOWN; + + /*get content type and mime type from file. */ + /*in case of drm file. */ + if (drm_svc_is_drm_file(path) == DRM_TRUE) { + DRM_FILE_TYPE drm_type = DRM_FILE_TYPE_NONE; + drm_type = drm_svc_get_drm_type(path); + if (drm_type == DRM_FILE_TYPE_NONE) { + *category = MS_CATEGORY_UNKNOWN; + return err; + } + else { + err = _ms_get_mime_by_drm_info(path, mimetype); + if (err < 0) { + *category = MS_CATEGORY_UNKNOWN; + return err; + } + *category |= MS_CATEGORY_DRM; + } + } + else { + /*in case of normal files */ + if (aul_get_mime_from_file(path, mimetype, sizeof(mimetype)) < 0) { + MS_DBG("aul_get_mime_from_file fail"); + *category = MS_CATEGORY_UNKNOWN; + return MS_ERR_ARG_INVALID; + } + } + + MS_DBG("mime type : %s", mimetype); + + /*categorize from mimetype */ + for (i = 0; i < CONTENT_TYPE_NUM; i++) { + if (strstr(mimetype, content_category[i].content_type) != NULL) { + *category = (*category | content_category[i].category_by_mime); + break; + } + } + + /*in application type, exitst sound file ex) x-smafs */ + if (*category & MS_CATEGORY_ETC) { + int prefix_len = strlen(content_category[0].content_type); + + for (i = 0; i < SOUND_MIME_NUM; i++) { + if (strstr(mimetype + prefix_len, sound_mime_table[i]) != NULL) { + *category ^= MS_CATEGORY_ETC; + *category |= MS_CATEGORY_SOUND; + break; + } + } + } + + /*check music file in soun files. */ + if (*category & MS_CATEGORY_SOUND) { + int prefix_len = strlen(content_category[0].content_type) + 1; + + MS_DBG("mime_type : %s", mimetype + prefix_len); + + for (i = 0; i < MUSIC_MIME_NUM; i++) { + if (strcmp(mimetype + prefix_len, music_mime_table[i]) == 0) { + *category ^= MS_CATEGORY_SOUND; + *category |= MS_CATEGORY_MUSIC; + break; + } + } + } else if (*category & MS_CATEGORY_VIDEO) { + /*some video files don't have video stream. in this case it is categorize as music. */ + char *ext; + /*"3gp" and "mp4" must check video stream and then categorize in directly. */ + ext = strrchr(path, '.'); + if (ext != NULL) { + if ((strncasecmp(ext, _3GP_FILE, 4) == 0) || (strncasecmp(ext, _MP4_FILE, 5) == 0)) { + int audio = 0; + int video = 0; + + err = mm_file_get_stream_info(path, &audio, &video); + if (err == 0) { + if (audio > 0 && video == 0) { + *category ^= MS_CATEGORY_VIDEO; + *category |= MS_CATEGORY_MUSIC; + } + } + } + } + } + + MS_DBG("category_from_ext : %d", *category); + + return err; +} + +void ms_check_db_updating(void) +{ + int vconf_value = 0; + + /*wait if phone init is not finished. */ + while (1) { + ms_config_get_int(VCONFKEY_FILEMANAGER_DB_STATUS, &vconf_value); + + if (vconf_value != VCONFKEY_FILEMANAGER_DB_UPDATED) { + MS_DBG("iNoti waits till init_phone finishes..."); + sleep(2); + } else { + return; + } + } +} + +/**************************************************************************************************** +LIBMEDIA_INFO +*****************************************************************************************************/ + +#ifdef _WITH_MP_PB_ +void ms_update_valid_type_start(void) +{ + audio_svc_set_item_valid_start(MS_VALID_COUNT); + minfo_set_item_valid_start(MS_VALID_COUNT); +} + +void ms_update_valid_type_end(void) +{ + audio_svc_set_item_valid_end(); + minfo_set_item_valid_end(); +} + +int ms_change_valid_type(ms_store_type_t store_type, bool validation) +{ + MS_DBG_START(); + int res = MS_ERR_NONE; + int err; + + audio_svc_storage_type_e audio_storage; + minfo_store_type visual_storage; + + audio_storage = (store_type == MS_PHONE) + ? AUDIO_SVC_STORAGE_PHONE : AUDIO_SVC_STORAGE_MMC; + visual_storage = (store_type == MS_PHONE) + ? MINFO_PHONE : MINFO_MMC; + + err = audio_svc_set_db_valid(audio_storage, validation); + if (err < AUDIO_SVC_ERROR_NONE) { + MS_DBG("audio_svc_set_db_valid error :%d", err); + res = MS_ERR_DB_OPERATION_FAIL; + } + + err = minfo_set_db_valid(visual_storage, validation); + if (err < MB_SVC_ERROR_NONE) { + MS_DBG("minfo_set_db_valid : error %d", err); + res = MS_ERR_DB_OPERATION_FAIL; + } + + MS_DBG_END(); + + return res; +} + +#ifdef THUMB_THREAD +int ms_media_db_insert_with_thumb(const char *path, int category) +{ + MS_DBG_START(); + MS_DBG("%s", path); + + int ret = MS_ERR_NONE; + int err; + ms_store_type_t store_type; + audio_svc_category_type_e audio_category; + minfo_file_type visual_category; + audio_svc_storage_type_e storage; + + if (category & MS_CATEGORY_VIDEO ||category & MS_CATEGORY_IMAGE) { + visual_category = (category & MS_CATEGORY_IMAGE) + ? MINFO_ITEM_IMAGE : MINFO_ITEM_VIDEO; + err = minfo_add_media(path, visual_category); + if (err < 0) { + MS_DBG(" minfo_add_media error %d", err); + ret = MS_ERR_DB_INSERT_RECORD_FAIL; + } else { + char thumb_path[1024]; + + err = thumbnail_request_from_db(path, thumb_path, sizeof(thumb_path)); + if (err < 0) { + MS_DBG("thumbnail_request_from_db falied: %d", err); + } else { + MS_DBG("thumbnail_request_from_db success: %s", thumb_path); + } + } + + MS_DBG("IMAGE"); + } + else if (category & MS_CATEGORY_SOUND || category & MS_CATEGORY_MUSIC) { + store_type = ms_get_store_type_by_full(path); + + storage = (store_type == MS_MMC) + ? AUDIO_SVC_STORAGE_MMC : AUDIO_SVC_STORAGE_PHONE; + audio_category = (category & MS_CATEGORY_SOUND) + ? AUDIO_SVC_CATEGORY_SOUND : AUDIO_SVC_CATEGORY_MUSIC; + + err = audio_svc_insert_item(storage, path, audio_category); + if (err < 0) { + MS_DBG("mp_svc_insert_item fails error %d", err); + ret = MS_ERR_DB_INSERT_RECORD_FAIL; + } + MS_DBG("SOUND"); + } + + MS_DBG_END(); + return ret; +} +#endif + +int ms_media_db_insert(const char *path, int category, bool bulk) +{ + MS_DBG_START(); + MS_DBG("%s", path); + + int ret = MS_ERR_NONE; + int err; + ms_store_type_t store_type; + audio_svc_category_type_e audio_category; + minfo_file_type visual_category; + audio_svc_storage_type_e storage; + + if (category & MS_CATEGORY_VIDEO ||category & MS_CATEGORY_IMAGE) { + visual_category = (category & MS_CATEGORY_IMAGE) + ? MINFO_ITEM_IMAGE : MINFO_ITEM_VIDEO; + if(bulk) + err = minfo_add_media_batch(path, visual_category); + else + err = minfo_add_media(path, visual_category); + if (err < 0) { + MS_DBG(" minfo_add_media error %d", err); + ret = MS_ERR_DB_INSERT_RECORD_FAIL; + } +#ifndef THUMB_THREAD + else { + char thumb_path[1024]; + + err = thumbnail_request_from_db(path, thumb_path, sizeof(thumb_path)); + if (err < 0) { + MS_DBG("thumbnail_request_from_db falied: %d", err); + } else { + MS_DBG("thumbnail_request_from_db success: %s", thumb_path); + } +#endif + } + + MS_DBG("IMAGE"); + } + else if (category & MS_CATEGORY_SOUND || category & MS_CATEGORY_MUSIC) { + store_type = ms_get_store_type_by_full(path); + + storage = (store_type == MS_MMC) + ? AUDIO_SVC_STORAGE_MMC : AUDIO_SVC_STORAGE_PHONE; + audio_category = (category & MS_CATEGORY_SOUND) + ? AUDIO_SVC_CATEGORY_SOUND : AUDIO_SVC_CATEGORY_MUSIC; + + err = audio_svc_insert_item(storage, path, audio_category); + if (err < 0) { + MS_DBG("mp_svc_insert_item fails error %d", err); + ret = MS_ERR_DB_INSERT_RECORD_FAIL; + } + MS_DBG("SOUND"); + } + + MS_DBG_END(); + return ret; +} + +int ms_check_file_exist_in_db(const char *path) +{ + int err; + int category; + Mitem *mi = NULL; + + /*get an item based on its url. */ + err = minfo_get_item(path, &mi); + if (err != MS_ERR_NONE) { + err = audio_svc_check_item_exist(path); + if (err != MS_ERR_NONE) + category = MS_CATEGORY_UNKNOWN; + else + category = MS_CATEGORY_MUSIC; + } else { + category = MS_CATEGORY_IMAGE; + } + + minfo_destroy_mtype_item(mi); + MS_DBG("Category : %d", category); + + return category; +} + +int ms_media_db_delete(const char *path) +{ + MS_DBG_START(); + int ret = MS_ERR_NONE; + int category; + ms_ignore_file_info *ignore_file; + + category = ms_check_file_exist_in_db(path); + + if (category & MS_CATEGORY_VIDEO || category & MS_CATEGORY_IMAGE) { + ret = minfo_delete_media(path); + if (ret != MS_ERR_NONE) { + MS_DBG("minfo_delete_media error : %d", ret); + return ret; + } + MS_DBG("VIDEO or IMAGE"); + } else if (category & MS_CATEGORY_MUSIC || category & MS_CATEGORY_SOUND) { + ret = audio_svc_delete_item_by_path(path); + if (ret != MS_ERR_NONE) { + MS_DBG("audio_svc_delete_item_by_path error : %d", ret); + return ret; + } + MS_DBG("MUSIC or SOUND"); + } +#ifdef _WITH_DRM_SERVICE_ + drm_svc_unregister_file(path, false); +#endif + + ignore_file = ms_inoti_find_ignore_file(path); + if (ignore_file != NULL) + ms_inoti_delete_ignore_file(ignore_file); + + MS_DBG_END(); + + return ret; +} + +void ms_media_db_move_start(void) +{ + audio_svc_move_item_start(MS_MOVE_COUNT); +} + +void ms_media_db_move_end(void) +{ + audio_svc_move_item_end(); +} + +int +ms_media_db_move(ms_store_type_t src_store, ms_store_type_t dst_store, + const char *src_path, const char *dst_path) +{ + MS_DBG_START(); + + int category = MS_CATEGORY_UNKNOWN; + minfo_file_type visual_category; + audio_svc_storage_type_e dst_storage; + audio_svc_storage_type_e src_storage; + int ret = 0; + + ret = ms_get_category_from_mime(dst_path, &category); + if (ret != MS_ERR_NONE) { + MS_DBG("ms_get_category_from_mime error %d", ret); + return ret; + } + + MS_DBG("category = %d", category); + + if (category & MS_CATEGORY_IMAGE || category & MS_CATEGORY_VIDEO) { + visual_category = (category & MS_CATEGORY_IMAGE) ? MINFO_ITEM_IMAGE : MINFO_ITEM_VIDEO; + ret = minfo_move_media(src_path, dst_path, visual_category); + if (ret != MB_SVC_ERROR_NONE) { + MS_DBG("minfo_move_media error : %d", ret); + return ret; + } + MS_DBG("VISUAL"); + } else if (category & MS_CATEGORY_MUSIC || category & MS_CATEGORY_SOUND) { + src_storage = (src_store == MS_MMC) ? AUDIO_SVC_STORAGE_MMC : AUDIO_SVC_STORAGE_PHONE; + dst_storage = (dst_store == MS_MMC) ? AUDIO_SVC_STORAGE_MMC : AUDIO_SVC_STORAGE_PHONE; + + ret = audio_svc_move_item(src_storage, src_path, dst_storage, dst_path); + if (ret < 0) { + MS_DBG("mp_svc_move_item error : %d", ret); + if (ret == AUDIO_SVC_ERROR_DB_NO_RECORD) { + MS_DBG(" This is a new file, Add DB"); + /*if source file does not exist in DB, it is new file. */ + + ret = ms_register_file(dst_path, NULL); + + if (ret != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", ret); + return MS_ERR_DB_INSERT_RECORD_FAIL; + } + } + + return ret; + } + MS_DBG("AUDIO"); + } + + MS_DBG_END(); + + return ret; +} + +bool ms_delete_all_record(ms_store_type_t store_type) +{ + MS_DBG_START(); + int err = 0; + minfo_store_type visual_storage; + audio_svc_storage_type_e audio_storage; + + visual_storage = (store_type == MS_PHONE) ? MINFO_PHONE : MINFO_MMC; + audio_storage = (store_type == MS_PHONE) ? AUDIO_SVC_STORAGE_PHONE : AUDIO_SVC_STORAGE_MMC; + + /* To reset media db when differnet mmc is inserted. */ + err = audio_svc_delete_all(audio_storage); + if (err != AUDIO_SVC_ERROR_NONE) { + MS_DBG("audio_svc_delete_all error : %d\n", err); +#if 0 /*except temporary*/ + return false; +#endif + } + + err = minfo_delete_invalid_media_records(visual_storage); + if (err != MB_SVC_ERROR_NONE) { + MS_DBG("minfo_delete_invalid_media_records error : %d\n", err); + return false; + } + + MS_DBG_END(); + + return true; +} +#endif/*_WITH_MP_PB_*/ + +#ifdef PROGRESS +void ms_create_quickpanel(struct quickpanel *ms_quickpanel) +{ + MS_DBG_START(); + int type_id; + int ret; + + struct quickpanel_type *qp_type; + + ret = quickpanel_get_type_id(NULL, + "/opt/apps/com.samsung.myfile/res/icons/default/small/com.samsung.myfile.png", + 0); + MS_DBG("return value of quickpanel_get_type_id : %d", ret); + + ms_quickpanel->type = ret; + ms_quickpanel->priv_id = getpid(); + ms_quickpanel->group_id = 0; + ms_quickpanel->title = "Media scanning"; + ms_quickpanel->content = NULL; + ms_quickpanel->progress = 0; + ms_quickpanel->args = NULL; + ms_quickpanel->args_group = NULL; + ms_quickpanel->evt = QP_E_ONGOING; + + ret = quickpanel_insert(ms_quickpanel); + MS_DBG("return value of quickpanel_insert : %d", ret); + + MS_DBG_END(); +} + +void ms_update_progress(struct quickpanel *ms_quickpanel, double progress) +{ + MS_DBG_START(); + + MS_DBG("%lf", progress) + quickpanel_update_progress(ms_quickpanel->type, + ms_quickpanel->priv_id, progress); + + MS_DBG_END(); +} + +void ms_delete_quickpanel(struct quickpanel *ms_quickpanel) +{ + MS_DBG_START(); + int ret = 0; + + ret = quickpanel_delete(ms_quickpanel->type, ms_quickpanel->priv_id); + MS_DBG("return value of quickpanel_delete : %d", ret); + + MS_DBG_END(); +} +#endif /*PROGRESS*/ + diff --git a/common/media-server-hibernation.c b/common/media-server-hibernation.c new file mode 100755 index 0000000..8efe944 --- /dev/null +++ b/common/media-server-hibernation.c @@ -0,0 +1,132 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-hibernation.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief This file defines api utilities of contents manager engines. + */ +#ifdef _USE_HIB + +#include <vconf.h> +#include <heynoti.h> + +#include "media-server-common.h" +#include "media-server-hibernation.h" +#include "media-server-inotify.h" +#include "media-server-scan.h" +extern int hib_fd; +extern GAsyncQueue *scan_queue; +extern GMutex *db_mutex; + +void _hibernation_leave_callback(void *data) +{ + GThread *inoti_tid; + GThread *scan_tid; + GMainLoop *mainloop = NULL; + + MS_DBG("hibernation leave callback\n"); + MS_DBG("MEDIA SERVER START[HIB]"); + + if (!g_thread_supported()) { + g_thread_init(NULL); + } + + if (!scan_queue) + scan_queue = g_async_queue_new(); + + /*Init db mutex variable*/ + if (!db_mutex) + db_mutex = g_mutex_new(); + + ms_inoti_init(); + + inoti_tid = g_thread_create((GThreadFunc) ms_inoti_thread, NULL, FALSE, NULL); + scan_tid = g_thread_create((GThreadFunc) ms_scan_thread, NULL, TRUE, NULL); +#ifdef THUMB_THREAD + /*create making thumbnail thread*/ + thumb_tid = g_thread_create((GThreadFunc) ms_thumb_thread, NULL, TRUE, NULL); +#endif + mainloop = g_main_loop_new(NULL, FALSE); + + ms_start(); + + MS_DBG("*****************************************"); + MS_DBG("*** Server of File Manager is running ***"); + MS_DBG("*****************************************"); + + g_main_loop_run(mainloop); + + /*free all associated memory */ + g_main_loop_unref(mainloop); + + if (scan_queue) + g_async_queue_unref(scan_queue); + + ms_end(); + exit(0); +} + +void _hibernation_enter_callback(void *data) +{ + + MS_DBG("[fm-server] hibernation enter callback\n"); + + /* IMPORTANT : this is for kill inotify thread + * it is essential for hibernation */ + ms_scan_data_t *scan_data; + + scan_data = malloc(sizeof(ms_scan_data_t)); + scan_data->scan_type = end_thread; + + g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); + + mkdir("/opt/media/_HIBERNATION_END", 0777); + rmdir("/opt/media/_HIBERNATION_END"); + + if (scan_queue) + g_async_queue_unref(scan_queue); + + ms_end(); + + if (hib_fd != 0) + heynoti_close(hib_fd); +} + +int _hibernation_initialize(void) +{ + hib_fd = heynoti_init(); + heynoti_subscribe(hib_fd, "HIBERNATION_ENTER", + _hibernation_enter_callback, (void *)hib_fd); + heynoti_subscribe(hib_fd, "HIBERNATION_LEAVE", + _hibernation_leave_callback, (void *)hib_fd); + heynoti_attach_handler(hib_fd); + return hib_fd; +} + +void _hibernation_fianalize(void) +{ + heynoti_close(hib_fd); +} +#endif diff --git a/common/media-server-inotify-internal.c b/common/media-server-inotify-internal.c new file mode 100755 index 0000000..78e2d74 --- /dev/null +++ b/common/media-server-inotify-internal.c @@ -0,0 +1,142 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-inotify-internal.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief23 + */ +#include "media-server-global.h" +#include "media-server-common.h" +#include "media-server-inotify-internal.h" + +int inoti_fd; +ms_create_file_info *latest_create_file; +extern ms_dir_data *first_inoti_node; + +int _ms_inoti_add_create_file_list(int wd, char *name) +{ + ms_create_file_info *new_node; + + new_node = malloc(sizeof(ms_create_file_info)); + new_node->name = strdup(name); + new_node->wd = wd; + + /*first created file */ + if (latest_create_file == NULL) { + latest_create_file = malloc(sizeof(ms_create_file_info)); + new_node->previous = NULL; + } else { + latest_create_file->next = new_node; + new_node->previous = latest_create_file; + } + new_node->next = NULL; + + latest_create_file = new_node; + + return MS_ERR_NONE; +} + +int _ms_inoti_delete_create_file_list(ms_create_file_info *node) +{ + if (node->previous != NULL) + node->previous->next = node->next; + if (node->next != NULL) + node->next->previous = node->previous; + + if (node == latest_create_file) { + latest_create_file = node->previous; + } + + free(node->name); + free(node); + + return MS_ERR_NONE; +} + +ms_create_file_info *_ms_inoti_find_create_file_list(int wd, char *name) +{ + ms_create_file_info *node = NULL; + node = latest_create_file; + + while (node != NULL) { + if ((node->wd == wd) && (strcmp(node->name, name) == 0)) { + return node; + } + + node = node->previous; + } + + return NULL; +} + +int _fex_is_default_path(const char *path) +{ + int ret = false; + + if ((strcmp(path, "Images and videos") == 0) || + (strcmp(path, "Sounds and music") == 0) || + (strcmp(path, "Downloads") == 0) || + (strcmp(path, "Camera shots") == 0) || + (strcmp(path, "Wallpapers") == 0) || + (strcmp(path, "Music") == 0) || + (strcmp(path, "Ringtones and Alerts") == 0) || + (strcmp(path, "FM Radio") == 0) || + (strcmp(path, "Voice recorder") == 0)) { + ret = true; + } + + return ret; +} + +bool _ms_inoti_get_full_path(int wd, char *name, char *path, int sizeofpath) +{ + int err; + ms_dir_data *node = NULL; + + if (name == NULL || path == NULL) + return false; + + if (first_inoti_node != NULL) { + node = first_inoti_node; + while (node->next != NULL) { + if (wd == node->wd) { + MS_DBG("find parent directory: %s", node->name); + break; + } + node = node->next; + } + } else { + MS_DBG("first_node is NULL"); + return false; + } + + err = ms_strappend(path, sizeofpath, "%s/%s", node->name, name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strappend error : %d", err); + return false; + } + MS_DBG("full path : %s", path); + return true; +} diff --git a/common/media-server-inotify.c b/common/media-server-inotify.c new file mode 100755 index 0000000..845cfd6 --- /dev/null +++ b/common/media-server-inotify.c @@ -0,0 +1,707 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-inotify.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include "media-server-global.h" +#include "media-server-common.h" +#include "media-server-inotify-internal.h" +#include "media-server-inotify.h" + +extern int inoti_fd; +ms_dir_data *first_inoti_node; +ms_ignore_file_info *latest_ignore_file; + +int _ms_inoti_directory_scan_and_register_file(char *dir_path) +{ + MS_DBG_START(); + struct dirent ent; + struct dirent *res = NULL; + DIR *dp = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + int err; + + if (dir_path == NULL) + return MS_ERR_INVALID_DIR_PATH; + + dp = opendir(dir_path); + if (dp == NULL) { + MS_DBG("Fail to open dir"); + return MS_ERR_DIR_OPEN_FAIL; + } + + ms_inoti_add_watch(dir_path); + + while (!readdir_r(dp, &ent, &res)) { + if (res == NULL) + break; + + if (ent.d_name[0] == '.') + continue; + + err = ms_strappend(path, sizeof(path), "%s/%s", dir_path, ent.d_name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strappend error : %d", err); + continue; + } + + /*in case of directory */ + if (ent.d_type == DT_DIR) { + _ms_inoti_directory_scan_and_register_file(path); + } else { + + err = ms_register_file(path, NULL); + if (err != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", err); + continue; + } + } + } + + closedir(dp); + + MS_DBG_END(); + + return 0; +} + +int _ms_inoti_scan_renamed_folder(char *org_path, char *chg_path) +{ + if (org_path == NULL || chg_path == NULL) { + MS_DBG("Parameter is wrong"); + return MS_ERR_ARG_INVALID; + } + + MS_DBG_START(); + + int err = -1; + struct dirent ent; + struct dirent *res = NULL; + + DIR *dp = NULL; + char path_from[MS_FILE_PATH_LEN_MAX] = { 0 }; + char path_to[MS_FILE_PATH_LEN_MAX] = { 0 }; + ms_store_type_t src_storage = 0; + ms_store_type_t des_storage = 0; + + dp = opendir(chg_path); + if (dp == NULL) { + MS_DBG("Fail to open dir"); + return MS_ERR_DIR_OPEN_FAIL; + } else { + MS_DBG("Modify added watch"); + ms_inoti_modify_watch(org_path, chg_path); + } + + while (!readdir_r(dp, &ent, &res)) { + if (res == NULL) + break; + + if (ent.d_name[0] == '.') + continue; + + err = ms_strappend(path_from, sizeof(path_from), "%s/%s", org_path, ent.d_name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strappend error : %d", err); + continue; + } + + err = ms_strappend(path_to, sizeof(path_to), "%s/%s", chg_path, ent.d_name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strappend error : %d", err); + continue; + } + + /*in case of directory */ + if (ent.d_type == DT_DIR) { + _ms_inoti_scan_renamed_folder(path_from, path_to); + } + + /*in case of file */ + if (ent.d_type == DT_REG) { + src_storage = ms_get_store_type_by_full(path_from); + des_storage = ms_get_store_type_by_full(path_to); + + if ((src_storage != MS_ERR_INVALID_FILE_PATH) + && (des_storage != MS_ERR_INVALID_FILE_PATH)) + ms_media_db_move(src_storage, des_storage, path_from, path_to); + else { + MS_DBG("ms_get_store_type_by_full error"); + } + } + } + + closedir(dp); + + MS_DBG_END(); + return 0; +} + +int ms_inoti_add_ignore_file(const char *path) +{ + ms_ignore_file_info *new_node; + + new_node = malloc(sizeof(ms_ignore_file_info)); + new_node->path = strdup(path); + + /*first created file */ + if (latest_ignore_file == NULL) { + latest_ignore_file = malloc(sizeof(ms_ignore_file_info)); + new_node->previous = NULL; + } else { + latest_ignore_file->next = new_node; + new_node->previous = latest_ignore_file; + } + new_node->next = NULL; + + latest_ignore_file = new_node; + + return MS_ERR_NONE; +} + +int ms_inoti_delete_ignore_file(ms_ignore_file_info * delete_node) +{ + MS_DBG(""); + if (delete_node->previous != NULL) + delete_node->previous->next = delete_node->next; + if (delete_node->next != NULL) + delete_node->next->previous = delete_node->previous; + + if (delete_node == latest_ignore_file) { + latest_ignore_file = delete_node->previous; + } + + free(delete_node->path); + free(delete_node); + + MS_DBG(""); + + return MS_ERR_NONE; +} + +ms_ignore_file_info *ms_inoti_find_ignore_file(const char *path) +{ + ms_ignore_file_info *node = NULL; + + node = latest_ignore_file; + while (node != NULL) { + if (strcmp(node->path, path) == 0) { + return node; + } + + node = node->previous; + } + + return NULL; +} + +void ms_inoti_delete_mmc_ignore_file(void) +{ + MS_DBG_START(); + ms_ignore_file_info *prv_node = NULL; + ms_ignore_file_info *cur_node = NULL; + ms_ignore_file_info *del_node = NULL; + + if (latest_ignore_file != NULL) { + cur_node = latest_ignore_file; + while (cur_node != NULL) { + if (strstr(cur_node->path, MS_MMC_ROOT_PATH) != NULL) { + if (prv_node != NULL) { + prv_node->previous = cur_node->previous; + } + + if (cur_node == latest_ignore_file) + latest_ignore_file = latest_ignore_file->previous; + + del_node = cur_node; + } else { + prv_node = cur_node; + } + + cur_node = cur_node->previous; + + if (del_node != NULL) { + free(del_node->path); + free(del_node); + del_node = NULL; + } + } + } + + /*active flush */ + malloc_trim(0); + + MS_DBG_END(); +} + +int ms_inoti_init(void) +{ + inoti_fd = inotify_init(); + if (inoti_fd < 0) { + perror("inotify_init"); + MS_DBG("inotify_init failed"); + return inoti_fd; + } + + return MS_ERR_NONE; +} + +void ms_inoti_add_watch(char *path) +{ + MS_DBG(""); + ms_dir_data *current_dir = NULL; + ms_dir_data *prv_node = NULL; + ms_dir_data *last_node = NULL; + + /*find same folder */ + if (first_inoti_node != NULL) { + MS_DBG("find same folder"); + last_node = first_inoti_node; + while (last_node != NULL) { + if (strcmp(path, last_node->name) == 0) { + MS_DBG("watch is already added: %s", path); + return; + } + prv_node = last_node; + last_node = last_node->next; + } + } + + MS_DBG("start add watch"); + + /*there is no same path. */ + current_dir = malloc(sizeof(ms_dir_data)); + current_dir->name = strdup(path); + current_dir->wd = inotify_add_watch(inoti_fd, path, + IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | + IN_MOVED_FROM | IN_MOVED_TO); + current_dir->next = NULL; + + if (first_inoti_node == NULL) { + first_inoti_node = current_dir; + } else { + /*if next node of current node is NULL, it is the lastest node. */ + MS_DBG("last_node : %s", prv_node->name); + prv_node->next = current_dir; + } + + MS_DBG("add watch : %s", path); +} + +int ms_inoti_add_watch_with_node(ms_dir_scan_info * const node) +{ + char full_path[MS_FILE_PATH_LEN_MAX] = { 0 }; + ms_dir_data *current_dir = NULL; + ms_dir_data *last_node = NULL; + + ms_get_full_path_from_node(node, full_path); + + /*find same folder */ + if (first_inoti_node != NULL) { + last_node = first_inoti_node; + while (last_node->next != NULL) { + if (strcmp(full_path, last_node->name) == 0) { + MS_DBG("watch is already added: %s", full_path); + return MS_ERR_NONE; + } + last_node = last_node->next; + } + } + + /*there is no same path. */ + current_dir = malloc(sizeof(ms_dir_data)); + current_dir->name = strdup(full_path); + current_dir->wd = + inotify_add_watch(inoti_fd, full_path, + IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | + IN_MOVED_FROM | IN_MOVED_TO); + current_dir->next = NULL; + current_dir->db_updated = false; + + if (first_inoti_node == NULL) { + first_inoti_node = current_dir; + } else { + /*if next node of current node is NULL, it is the lastest node. */ + MS_DBG("last_node : %s", last_node->name); + last_node->next = current_dir; + } + MS_DBG("add watch : %s", full_path); + + return MS_ERR_NONE; +} + +void ms_inoti_remove_watch_recursive(char *path) +{ + MS_DBG_START(); + ms_dir_data *prv_node = NULL; + ms_dir_data *cur_node = NULL; + ms_dir_data *del_node = NULL; + + if (first_inoti_node != NULL) { + cur_node = first_inoti_node; + while (cur_node != NULL) { + if (strstr(cur_node->name, path) != NULL) { + if (prv_node != NULL) { + prv_node->next = + cur_node->next; + } + + if (cur_node == first_inoti_node) + first_inoti_node = + first_inoti_node->next; + + del_node = cur_node; + } else { + prv_node = cur_node; + } + + cur_node = cur_node->next; + + if (del_node != NULL) { + free(del_node->name); + free(del_node); + del_node = NULL; + } + } + } + + /*active flush */ + malloc_trim(0); + + MS_DBG_END(); +} + +void ms_inoti_remove_watch(char *path) +{ + ms_dir_data *del_node = NULL; + ms_dir_data *prv_node = NULL; + + if (strcmp(first_inoti_node->name, path) == 0) { + del_node = first_inoti_node; + first_inoti_node = first_inoti_node->next; + } else { + /*find same folder */ + if (first_inoti_node != NULL) { + del_node = first_inoti_node; + while (del_node != NULL) { + MS_DBG("current node %s", del_node->name); + if (strcmp(path, del_node->name) == 0) { + MS_DBG("find delete node: %s", del_node->name); + if (prv_node != NULL) { + MS_DBG("previous_node : %s", prv_node->name); + prv_node->next = del_node->next; + } + /*free deleted node */ + free(del_node->name); + free(del_node); + break; + } + prv_node = del_node; + del_node = del_node->next; + } + } + } + + /*active flush */ + malloc_trim(0); +} + +void ms_inoti_modify_watch(char *path_from, char *path_to) +{ + ms_dir_data *mod_node; + + if (strcmp(first_inoti_node->name, path_from) == 0) { + mod_node = first_inoti_node; + } else { + /*find same folder */ + if (first_inoti_node != NULL) { + mod_node = first_inoti_node; + while (mod_node->next != NULL) { + if (strcmp(path_from, mod_node->name) == 0) { + MS_DBG("find change node: %s", + mod_node->name); + break; + } + mod_node = mod_node->next; + } + } + } + + /*free previous name of node */ + free(mod_node->name); + mod_node->name = NULL; + + /*add new name */ + mod_node->name = strdup(path_to); + + /*active flush */ + malloc_trim(0); +} + + +gboolean ms_inoti_thread(void *data) +{ + uint32_t i; + int length; + int err; + int prev_mask = 0; + int prev_wd = -1; + bool res; + char name[MS_FILE_NAME_LEN_MAX + 1] = { 0 }; + char prev_name[MS_FILE_NAME_LEN_MAX + 1] = { 0 }; + char buffer[INOTI_BUF_LEN] = { 0 }; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + struct inotify_event *event; + + MS_DBG("START INOTIFY"); + + err = ms_media_db_open(); + if (err != MS_ERR_NONE) { + MS_DBG(" INOTIFY : sqlite3_open: ret = %d", err); + return false; + } + + while (1) { + i = 0; + length = read(inoti_fd, buffer, sizeof(buffer) - 1); + + if (length < 0 || length > sizeof(buffer)) { /*this is error */ + MS_DBG("fail read"); + perror("read"); + continue; + } + + while (i < length && i < INOTI_BUF_LEN) { + /*it's possible that ums lets reset phone data... */ + event = (struct inotify_event *)&buffer[i]; + + /*stop this threadfor hibernation */ + if (strcmp(event->name, "_HIBERNATION_END") == 0) { + /*db close before capture hibernatio image */ + err = ms_media_db_close(); + if (err != MS_ERR_NONE) { + MS_DBG("failed ms_media_db_close : ret = (%d)", err); + } + return false; + } else if(strcmp(event->name, "_FILEOPERATION_END") == 0) { + /*file operation is end*/ + /* announce db is updated*/ + ms_set_db_status(MS_DB_UPDATED); + rmdir("/opt/media/_FILEOPERATION_END"); + goto NEXT_INOTI_EVENT; + } else if (event->name[0] == '.') { + /*event of hidden folder is ignored */ + MS_DBG("Ignore : First character of event->name includes invalid character"); + goto NEXT_INOTI_EVENT; + } else if (event->wd < 1) { + /*this is error */ + MS_DBG("invalid wd : %d", event->wd); + goto NEXT_INOTI_EVENT; + } + + /*start of one event */ + if (event->len && (event->len <= MS_FILE_NAME_LEN_MAX)) { + /*Add for fixing prevent defect 2011-02-15 */ + err = ms_strcopy(name, sizeof(name), "%s", event->name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strcopy error : %d", err); + goto NEXT_INOTI_EVENT; + } + + /*get full path of file or directory */ + res = _ms_inoti_get_full_path(event->wd, name, path, sizeof(path)); + if (res == false) { + MS_DBG("_ms_inoti_get_full_path error"); + goto NEXT_INOTI_EVENT; + } + + MS_DBG("INOTIFY[%d : %s]", event->wd, name); + if (event->mask & IN_ISDIR) { + MS_DBG("DIRECTORY INOTIFY"); + + if (event->mask & IN_MOVED_FROM) { + MS_DBG("MOVED_FROM"); + + prev_mask = event->mask; + prev_wd = event->wd; + + err = ms_strcopy(prev_name, sizeof(prev_name), "%s", event->name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strcopy fail"); + goto NEXT_INOTI_EVENT; + } + } + else if (event->mask & IN_MOVED_TO) { + MS_DBG("MOVED_TO"); + + char full_path_from[MS_FILE_PATH_LEN_MAX] = { 0 }; + + res = _ms_inoti_get_full_path(prev_wd, prev_name, full_path_from, sizeof(full_path_from)); + if (res == false) { + MS_DBG("_ms_inoti_get_full_path error"); + goto NEXT_INOTI_EVENT; + } + /*enable bundle commit*/ + ms_media_db_move_start(); + + /*need update file information under renamed directory */ + _ms_inoti_scan_renamed_folder(full_path_from, path); + + /*disable bundle commit*/ + ms_media_db_move_end(); + + if (_fex_is_default_path(prev_name)) { + if (strstr(path, MS_PHONE_ROOT_PATH)) { + fex_make_default_path(); + } else { + fex_make_default_path_mmc(); + } + } + prev_mask = prev_wd = 0; /*reset */ + } + else if (event->mask & IN_CREATE) { + MS_DBG("CREATE"); + + _ms_inoti_directory_scan_and_register_file(path); + prev_mask = event->mask; + } + else if (event->mask & IN_DELETE) { + MS_DBG("DELETE"); + + ms_inoti_remove_watch(path); + + if (_fex_is_default_path(name)) { + if (strstr(path, MS_PHONE_ROOT_PATH)) { + fex_make_default_path(); + } else { + fex_make_default_path_mmc(); + } + } + } + } + else { + MS_DBG("FILE INOTIFY"); + + if (event->mask & IN_MOVED_FROM) { + MS_DBG("MOVED_FROM"); + + err = ms_media_db_delete(path); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_delete fail error : %d", err); + } + } + else if (event->mask & IN_MOVED_TO) { + MS_DBG("MOVED_TO"); + + err = ms_register_file(path, NULL); + if (err != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", err); + } + } + else if (event->mask & IN_CREATE) { + MS_DBG("CREATE"); + + _ms_inoti_add_create_file_list(event->wd, name); + } + else if (event->mask & IN_DELETE) { + MS_DBG("DELETE"); + + err = ms_media_db_delete(path); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_delete error : %d", err); + } + } + else if (event->mask & IN_CLOSE_WRITE) { + MS_DBG("CLOSE_WRITE"); + + ms_create_file_info *node; + node = _ms_inoti_find_create_file_list (event->wd, name); + + if (node != NULL || ((prev_mask & IN_ISDIR) & IN_CREATE)) { + + err = ms_register_file(path, NULL); + if (err != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", err); + } + if (node != NULL) + _ms_inoti_delete_create_file_list(node); + } + else { + /*in case of replace */ + MS_DBG("This case is replacement or changing meta data."); + ms_ignore_file_info *ignore_file; + + ignore_file = ms_inoti_find_ignore_file(path); + if (ignore_file == NULL) { + err = ms_media_db_delete(path); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_delete error : %d", err); + } + /*update = delete + regitster */ + err = ms_register_file(path, NULL); + if (err != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", err); + goto NEXT_INOTI_EVENT; + } + } else { + MS_DBG(" Ignore this file"); + } + } + prev_mask = prev_wd = 0; /*reset */ + } + } + } /*end of one event */ + else { + MS_DBG("Event length is zero or over MS_FILE_NAME_LEN_MAX"); + if (event->mask & IN_IGNORED) { + MS_DBG("This case is ignored"); + } + } + NEXT_INOTI_EVENT: ; + i += INOTI_EVENT_SIZE + event->len; + } + /*Active flush */ + sqlite3_release_memory(-1); + malloc_trim(0); + } + + ms_inoti_remove_watch(MS_DB_UPDATE_NOTI_PATH); + + ms_inoti_remove_watch_recursive(MS_PHONE_ROOT_PATH); + ms_inoti_remove_watch_recursive(MS_MMC_ROOT_PATH); + + close(inoti_fd); + + err = ms_media_db_close(); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_close error : %d", err); + return false; + } + MS_DBG("Disconnect MEDIA DB"); + + return false; +} diff --git a/common/media-server-main.c b/common/media-server-main.c new file mode 100755 index 0000000..1f15753 --- /dev/null +++ b/common/media-server-main.c @@ -0,0 +1,240 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-mainl.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include <vconf.h> + +#include "media-server-common.h" +#include "media-server-hibernation.h" +#include "media-server-inotify.h" +#include "media-server-scan.h" +#include "media-server-socket.h" +#ifdef THUMB_THREAD +#include "media-server-thumb.h" +#endif + +#include <heynoti.h> + +#define APP_NAME "media-server" + +#ifdef _USE_HIB +int hib_fd = 0; +#endif +extern GAsyncQueue *scan_queue; +extern GAsyncQueue* ret_queue; +extern GMutex *db_mutex; +extern GMutex *list_mutex; +extern GMutex *queue_mutex; +extern GArray *reg_list; + +bool check_process(pid_t current_pid) +{ + MS_DBG_START(); + DIR *pdir; + struct dirent pinfo; + struct dirent *result = NULL; + bool ret = false; + int find_pid = 0; + + pdir = opendir("/proc"); + if (pdir == NULL) { + MS_DBG("err: NO_DIR\n"); + return 0; + } + + while (!readdir_r(pdir, &pinfo, &result)) { + if (result == NULL) + break; + + if (pinfo.d_type != 4 || pinfo.d_name[0] == '.' + || pinfo.d_name[0] > 57) + continue; + + FILE *fp; + char buff[128]; + char path[128]; + + ms_strcopy(path, sizeof(path), "/proc/%s/status", pinfo.d_name); + fp = fopen(path, "rt"); + if (fp) { + fgets(buff, 128, fp); + fclose(fp); + + if (strstr(buff, APP_NAME)) { + MS_DBG("pinfo->d_name : %s", pinfo.d_name); + find_pid = atoi(pinfo.d_name); + MS_DBG(" find_pid : %d", find_pid); + MS_DBG(" current_pid : %d", current_pid); + if (find_pid == current_pid) + ret = true; + else { + ret = false; + break; + } + } + } else { + MS_DBG("Can't read file [%s]", path); + } + } + + closedir(pdir); + + MS_DBG_END(); + + return ret; +} + +void init_process() +{ + +} + +static bool _db_clear(void) + { + int err; + int db_status; + int usb_status; + bool need_db_create = false; + + /*connect to media db, if conneting is failed, db updating is stopped*/ + ms_media_db_open(); + + /*update just valid type*/ + err = ms_change_valid_type(MS_MMC, false); + if (err != MS_ERR_NONE) + MS_DBG("ms_change_valid_type fail"); + + ms_config_get_int(VCONFKEY_FILEMANAGER_DB_STATUS, &db_status); + ms_config_get_int(MS_USB_MODE_KEY, &usb_status); + + MS_DBG("finish_phone_init_data db = %d", db_status); + MS_DBG("finish_phone_init_data usb = %d", usb_status); + + if (db_status == VCONFKEY_FILEMANAGER_DB_UPDATING + || usb_status == MS_VCONFKEY_MASS_STORAGE_MODE) { + + need_db_create = true; + + err = ms_change_valid_type(MS_PHONE, false); + if (err != MS_ERR_NONE) + MS_DBG("ms_change_valid_type fail"); + } + + ms_set_db_status(MS_DB_UPDATED); + + /*disconnect form media db*/ + ms_media_db_close(); + + return need_db_create; +} + +int main(int argc, char **argv) +{ + GThread *inoti_tid; + GThread *scan_tid; + GThread *scoket_tid; + + GMainLoop *mainloop = NULL; + pid_t current_pid = 0; + bool check_result = false; + int err; + bool need_db_create; + + current_pid = getpid(); + check_result = check_process(current_pid); + if (check_result == false) + exit(0); + + if (!g_thread_supported()) { + g_thread_init(NULL); + } + + /*Init db mutex variable*/ + if (!db_mutex) + db_mutex = g_mutex_new(); + + need_db_create = _db_clear(); + +#ifdef _USE_HIB + _hibernation_initialize(); +#endif + + MS_DBG("MEDIA SERVER START"); + + if (!scan_queue) + scan_queue = g_async_queue_new(); + if (!ret_queue) + ret_queue = g_async_queue_new(); + + /*Init for register file*/ + if (!list_mutex) + list_mutex = g_mutex_new(); + if (!queue_mutex) + queue_mutex = g_mutex_new(); + if (!reg_list) + reg_list = g_array_new(TRUE, TRUE, sizeof(char*)); + + ms_inoti_init(); + + ms_inoti_add_watch(MS_DB_UPDATE_NOTI_PATH); + + /*inotify setup */ + inoti_tid = g_thread_create((GThreadFunc) ms_inoti_thread, NULL, FALSE, NULL); + scan_tid = g_thread_create((GThreadFunc) ms_scan_thread, NULL, TRUE, NULL); + scoket_tid = g_thread_create((GThreadFunc) ms_socket_thread, NULL, TRUE, NULL); + + mainloop = g_main_loop_new(NULL, FALSE); + + ms_start(need_db_create); + + MS_DBG("*****************************************"); + MS_DBG("*** Server of File Manager is running ***"); + MS_DBG("*****************************************"); + + g_main_loop_run(mainloop); + + /*free all associated memory */ + g_main_loop_unref(mainloop); + + if (scan_queue) + g_async_queue_unref(scan_queue); + + if (ret_queue) + g_async_queue_unref(ret_queue); + + if(reg_list) + g_array_free(reg_list, true); + + ms_end(); + +#ifdef _USE_HIB + _hibernation_fianalize(); +#endif + + exit(0); +} diff --git a/common/media-server-scan-internal.c b/common/media-server-scan-internal.c new file mode 100755 index 0000000..e3bfcba --- /dev/null +++ b/common/media-server-scan-internal.c @@ -0,0 +1,404 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-scan-internal.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + +#include <vconf.h> +#include <audio-svc-error.h> +#include <audio-svc.h> +#include <media-svc.h> +#include "media-server-common.h" +#include "media-server-inotify.h" +#include "media-server-scan-internal.h" + +#ifdef PROGRESS +#include <quickpanel.h> +#endif + +extern int mmc_state; +extern int current_usb_mode; +extern ms_dir_data *first_inoti_node; + +#ifdef PROGRESS +#define SIZE_OF_PBARRAY 100 +#endif + +int _ms_get_path_from_current_node(int find_folder, + ms_dir_scan_info **current_root, + ms_dir_scan_info **real_root, char **path) +{ + MS_DBG_START(); + + int err = 0; + char get_path[FAT_FILEPATH_LEN_MAX + 1] = { 0 }; + + if (find_folder == 0) { + if ((*current_root)->Rbrother != NULL) { + *current_root = (*current_root)->Rbrother; + } else { + while (1) { + if ((*current_root)->parent == *real_root + || (*current_root)->parent == NULL) { + *current_root = NULL; + MS_DBG_END(); + return 0; + } else if ((*current_root)->parent->Rbrother == + NULL) { + *current_root = (*current_root)->parent; + } else { + *current_root = + (*current_root)->parent->Rbrother; + break; + } + } + } + } + + err = ms_get_full_path_from_node(*current_root, get_path); + + *path = strdup(get_path); + + MS_DBG_END(); + + return err; +} + +#ifdef PROGRESS +void _ms_dir_check(char *start_path, ms_store_type_t db_type, unsigned short *file_count) +#else +void _ms_dir_check(char *start_path, ms_store_type_t db_type) +#endif +{ + MS_DBG_START(); + + int err = 0; + int find_folder = 0; + char get_path[MS_FILE_PATH_LEN_MAX] = { 0 }; + char *path; + DIR *dp = NULL; + struct dirent entry; + struct dirent *result; + + ms_dir_scan_info *root; + ms_dir_scan_info *tmp_root = NULL; + ms_dir_scan_info *cur_node = NULL; /*current node*/ + ms_dir_scan_info *prv_node = NULL; /*previous node*/ + ms_dir_scan_info *next_node = NULL; + + root = malloc(sizeof(ms_dir_scan_info)); + if (root == NULL) { + MS_DBG("malloc fail"); + return; + } + + root->name = strdup(start_path); + if (root->name == NULL) { + MS_DBG("strdup fail"); + free(root); + return; + } + + root->parent = NULL; + root->Rbrother = NULL; + root->next = NULL; + tmp_root = root; + prv_node = root; + + err = ms_get_full_path_from_node(tmp_root, get_path); + MS_DBG("full_path : %s", get_path); + + path = strdup(get_path); + if (path == NULL) { + MS_DBG("strdup fail"); + free(root); + return; + } + + ms_inoti_add_watch_with_node(root); + + while (1) { + dp = opendir(path); + if (dp == NULL) { + MS_DBG("%s folder opendir fails", path); + goto NEXT_DIR; + } + + while (!readdir_r(dp, &entry, &result)) { + if (result == NULL) + break; + + if (entry.d_name[0] == '.') + continue; + + /*check usb in out*/ + if (current_usb_mode != VCONFKEY_USB_STORAGE_STATUS_OFF + ||(( mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (db_type == MS_MMC))) { + + goto FREE_RESOURCES; + } + + if (entry.d_type & DT_DIR) { + DIR *tmp_dp = NULL; + err = ms_strappend(get_path, sizeof(get_path), "%s/%s",path, entry.d_name); + if (err != MS_ERR_NONE) { + MS_DBG("ms_strappend error"); + continue; + } + + tmp_dp = opendir(get_path); + if (tmp_dp == NULL) { + MS_DBG("%s folder opendir fails", get_path); + continue; + } + else + closedir(tmp_dp); + + cur_node = malloc(sizeof(ms_dir_scan_info)); + if (cur_node == NULL) { + MS_DBG("malloc fail"); + + goto FREE_RESOURCES; + } + + cur_node->name = strdup(entry.d_name); + cur_node->Rbrother = NULL; + cur_node->next = NULL; + + /*1. 1st folder */ + if (find_folder == 0) { + cur_node->parent = tmp_root; + tmp_root = cur_node; + } else { + cur_node->parent = tmp_root->parent; + prv_node->Rbrother = cur_node; + } + prv_node->next = cur_node; + + /*add watch */ + ms_inoti_add_watch_with_node(cur_node); + + /*change previous */ + prv_node = cur_node; + find_folder++; + } +#ifdef PROGRESS + else if (entry.d_type & DT_REG) { + (*file_count)++; + } +#endif + } +NEXT_DIR: + if (dp) closedir(dp); + if (path) free(path); + dp = NULL; + path = NULL; + + err = _ms_get_path_from_current_node(find_folder, &tmp_root, &root, &path); + if (err < 0) + break; + + if (tmp_root == NULL) + break; + + find_folder = 0; + } + +FREE_RESOURCES: + /*free allocated memory */ + if (path) free(path); + if (dp) closedir(dp); + + cur_node = root; + while (cur_node != NULL) { + next_node = cur_node->next; + free(cur_node->name); + free(cur_node); + cur_node = next_node; + } + + MS_DBG_END(); +} + +#ifdef PROGRESS +void _ms_dir_scan(ms_scan_data_t * scan_data, struct quickpanel *ms_quickpanel) +#else +void _ms_dir_scan(ms_scan_data_t * scan_data) +#endif +{ + MS_DBG_START(); + int err = 0; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + ms_dir_data *node; + DIR *dp = NULL; +#ifdef PROGRESS + int i; + unsigned short file_count = 0; + unsigned short update_count = 0; + unsigned short proress_array[SIZE_OF_PBARRAY] = { 0 }; +#endif + + if (scan_data->db_type == MS_PHONE) + err = ms_strcopy(path, sizeof(path), "%s", MS_PHONE_ROOT_PATH); + else + err = ms_strcopy(path, sizeof(path), "%s", MS_MMC_ROOT_PATH); + + if (err < MS_ERR_NONE) { + MS_DBG("fail ms_strcopy"); + } + +#ifdef PROGRESS + /*Add inotify watch */ + _ms_dir_check(path, scan_data->db_type,&file_count); +#else + /*Add inotify watch */ + _ms_dir_check(path, scan_data->db_type); +#endif + +#ifdef PROGRESS + for (i = 0; i < SIZE_OF_PBARRAY; i++) { + proress_array[i] = ((i + 1) * file_count) / SIZE_OF_PBARRAY; + if (proress_array[i] == 0) + proress_array[i] = 1; + } + i = 0; +#endif + + /*if scan type is not MS_SCAN_NONE, check data in db. */ + if (scan_data->scan_type == MS_SCAN_ALL + || scan_data->scan_type == MS_SCAN_PART) { + struct dirent entry; + struct dirent *result = NULL; + + node = first_inoti_node; +#ifdef PROGRESS + int progress = 0; + int pre_progress = 0; +#endif + if (scan_data->scan_type == MS_SCAN_PART) { + /*enable bundle commit*/ + ms_update_valid_type_start(); + } + + while (node != NULL) { + /*check usb in out */ + if (current_usb_mode != VCONFKEY_USB_STORAGE_STATUS_OFF + || ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (scan_data->db_type == MS_MMC))) { + MS_DBG("Directory scanning is stopped"); + goto STOP_SCAN; + } + if (node->db_updated != true) { + dp = opendir(node->name); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + if (result == NULL) + break; + + if (entry.d_name[0] == '.') + continue; + + /*check usb in out */ + if (current_usb_mode != VCONFKEY_USB_STORAGE_STATUS_OFF + || ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (scan_data->db_type == MS_MMC))) { + MS_DBG("Directory scanning is stopped"); + goto STOP_SCAN; + } + + if (entry.d_type & DT_REG) { + MS_DBG("THIS IS FEX_DIR_SCAN_CB"); +#ifdef PROGRESS + /*update progress bar */ + update_count++; + if (ms_quickpanel != NULL) { + if (proress_array[i] == update_count) { + while(1) { + ms_update_progress(ms_quickpanel, ((double)i) / 100); + i++; + if (proress_array[i] != update_count) + break; + } + } + } +#endif/*PROGRESS*/ + err = ms_strappend(path, sizeof(path), "%s/%s", node->name, entry.d_name); + if (err < 0) { + MS_DBG("FAIL : ms_strappend"); + continue; + } + + if (scan_data->scan_type == MS_SCAN_PART) + err = ms_update_valid_type(path); + else + err = ms_register_scanfile(path); + + if (err < 0) { + MS_DBG("failed to update db : %d , %d\n", err, scan_data->scan_type); + continue; + } + } + } + } else { + MS_DBG("%s folder opendir fails", node->name); + } + if (dp) closedir(dp); + dp = NULL; + + if (node == NULL) { + MS_DBG(""); + MS_DBG("DB updating is done"); + MS_DBG(""); + break; + } + node->db_updated = true; + } + node = node->next; + } /*db update while */ + + if (scan_data->scan_type == MS_SCAN_PART) { + /*disable bundle commit*/ + ms_update_valid_type_end(); + + audio_svc_delete_invalid_items(scan_data->db_type); + minfo_delete_invalid_media_records(scan_data->db_type); + } + } else { + node = first_inoti_node; + + while (node != NULL) { + node->db_updated = true; + node = node->next; + } + } +STOP_SCAN: + if (dp) closedir(dp); + + sync(); + + MS_DBG_END(); + + return; +} diff --git a/common/media-server-scan.c b/common/media-server-scan.c new file mode 100755 index 0000000..ae440d5 --- /dev/null +++ b/common/media-server-scan.c @@ -0,0 +1,239 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-scan.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include <vconf.h> +#include <minfo-types.h> + +#include "media-server-common.h" +#include "media-server-thumb.h" +#include "media-server-scan-internal.h" +#include "media-server-scan.h" + +#ifdef PROGRESS +#include <quickpanel.h> +#endif + +GAsyncQueue *scan_queue; +extern int mmc_state; + +#ifdef FMS_PERF +extern struct timeval g_mmc_start_time; +extern struct timeval g_mmc_end_time; +#endif + +static void _insert_array(GArray *garray, ms_scan_data_t *insert_data) +{ + ms_scan_data_t *data; + bool insert_ok = false; + int len = garray->len; + int i; + + MS_DBG("the length of array : %d", len); + MS_DBG("db_type : %d", insert_data->db_type); + MS_DBG("scan_type : %d", insert_data->scan_type); + + for (i=0; i < len; i++) + { + data = g_array_index(garray, ms_scan_data_t*, i); + + if (data->db_type == insert_data->db_type) { + if(data->scan_type > insert_data->scan_type) { + g_array_remove_index (garray, i); + g_array_insert_val(garray, i, insert_data); + insert_ok = true; + } + } + } + + if (insert_ok == false) + g_array_append_val(garray, insert_data); +} + +gboolean ms_scan_thread(void *data) +{ + MS_DBG_START(); + + ms_scan_data_t *scan_data = NULL; + ms_scan_data_t *insert_data; + GArray *garray = NULL; + bool res; + int length; + int err; + +#ifdef PROGRESS + struct quickpanel *ms_quickpanel = NULL; +#endif + + /*create array for processing overlay data*/ + garray = g_array_new (FALSE, FALSE, sizeof (ms_scan_data_t *)); + if (garray == NULL) { + MS_DBG("g_array_new error"); + return false; + } + + while (1) { + length = g_async_queue_length(scan_queue); + + /*updating requests remain*/ + if (garray->len != 0 && length == 0) { + scan_data = g_array_index(garray, ms_scan_data_t*, 0); + g_array_remove_index (garray, 0); + } else if (length != 0) { + insert_data = g_async_queue_pop(scan_queue); + _insert_array(garray, insert_data); + continue; + } else if (garray->len == 0 && length == 0) { + /*Threre is no request, Wait until pushung new request*/ + insert_data = g_async_queue_pop(scan_queue); + _insert_array(garray, insert_data); + continue; + } + + if (scan_data->scan_type == end_thread) { + MS_DBG("RECEIVE END THREAD"); + free(scan_data); + + if(garray) g_array_free (garray, TRUE); + + return false; + } else if (scan_data->scan_type != MS_SCAN_VALID) { + /*connect to media db, if conneting is failed, db updating is stopped*/ + err = ms_media_db_open(); + if (err != MS_ERR_NONE) + continue; + + /*start db updating */ + if (scan_data->scan_type != MS_SCAN_NONE ) { + int status; + + ms_set_db_status(MS_DB_UPDATING); + /*check UMS status and change configuration value*/ + ms_config_get_int(MS_USB_MODE_KEY, &status); + if (status == MS_VCONFKEY_MASS_STORAGE_MODE) { + ms_config_get_int(VCONFKEY_USB_STORAGE_STATUS, &status); + if(status == VCONFKEY_USB_STORAGE_STATUS_OFF) { + ms_config_set_int(MS_USB_MODE_KEY, MS_VCONFKEY_NORMAL_MODE); + } + } +#ifdef PROGRESS + ms_quickpanel = malloc(sizeof(struct quickpanel)); + ms_create_quickpanel(ms_quickpanel); +#endif /*PROGRESS*/ + } + + if (scan_data->scan_type == MS_SCAN_ALL) { + res = ms_delete_all_record(scan_data->db_type); + if (res != true) { + MS_DBG("ms_delete_all_record fails"); + } + } + +#ifdef FMS_PERF + if (scan_data->db_type == MS_MMC) { + ms_check_start_time(&g_mmc_start_time); + } +#endif + /*call for bundle commit*/ + ms_register_start(); + +#ifdef PROGRESS + /*add inotify watch and insert data into media db */ + _ms_dir_scan(scan_data, ms_quickpanel); + + if (ms_quickpanel != NULL) { + ms_delete_quickpanel(ms_quickpanel); + free(ms_quickpanel); + ms_quickpanel = NULL; + } +#else + /*add inotify watch and insert data into media db */ + _ms_dir_scan(scan_data); +#endif + /*call for bundle commit*/ + ms_register_end(); + +#ifdef FMS_PERF + if (scan_data->db_type == MS_MMC) { + ms_check_end_time(&g_mmc_end_time); + ms_check_time_diff(&g_mmc_start_time, &g_mmc_end_time); + } +#endif + + /*set vconf key mmc loading for indicator */ + if (scan_data->scan_type != MS_SCAN_NONE ) + ms_set_db_status(MS_DB_UPDATED); + + /*disconnect form media db*/ + ms_media_db_close(); +#ifdef THUMB_THREAD + /*create making thumbnail thread*/ + if (scan_data->scan_type == MS_SCAN_ALL) { + minfo_folder_type db; + if(scan_data->db_type == MS_PHONE) + db = MINFO_CLUSTER_TYPE_LOCAL_PHONE; + else + db = MINFO_CLUSTER_TYPE_LOCAL_MMC; + g_thread_create((GThreadFunc) ms_thumb_thread, &db, TRUE, NULL); + } +#endif + /*Active flush */ + sqlite3_release_memory(-1); + + if (scan_data->db_type == MS_MMC) { + ms_update_mmc_info(); + } + } else { + /*connect to media db, if conneting is failed, db updating is stopped*/ + err = ms_media_db_open(); + if (err != MS_ERR_NONE) + continue; + + /*update just valid type*/ + err = ms_change_valid_type(scan_data->db_type, false); + if (err != MS_ERR_NONE) + MS_DBG("ms_change_valid_type fail"); + + ms_set_db_status(MS_DB_UPDATED); + + /*disconnect form media db*/ + ms_media_db_close(); + + /*Active flush */ + sqlite3_release_memory(-1); + } + + free(scan_data); + } /*thread while*/ + + if(garray) g_array_free (garray, TRUE); + + MS_DBG_END(); + + return true; +} diff --git a/common/media-server-socket.c b/common/media-server-socket.c new file mode 100755 index 0000000..bda3145 --- /dev/null +++ b/common/media-server-socket.c @@ -0,0 +1,147 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-thumb.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <media-util-err.h> +#include <media-info.h> + +#include "media-server-global.h" +#include "media-server-common.h" +#include "media-server-socket.h" + +#define MINFO_REGISTER_PORT 1001 + +GAsyncQueue* ret_queue; + +gboolean ms_socket_thread(void *data) +{ + int ret; + int err; + int state; + int sockfd; + int send_msg = MEDIA_INFO_ERROR_NONE; + int client_addr_size; + + struct sockaddr_in server_addr; + struct sockaddr_in client_addr; + + char recv_buff[MS_FILE_PATH_LEN_MAX]; + + sockfd = socket(PF_INET, SOCK_DGRAM, 0); + + if(sockfd < 0) + { + MS_DBG("socket create error"); + perror("socket error : "); + return MS_ERR_SOCKET_CONN; + } + + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(MINFO_REGISTER_PORT); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + state = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); + if(state < 0) + { + MS_DBG("bind error"); + perror("bind error : "); + return MS_ERR_SOCKET_BIND; + } + + err = ms_media_db_open(); + if (err != MS_ERR_NONE) { + MS_DBG("SOCKET : sqlite3_open: ret = %d", err); + return false; + } + + while(1) + { + client_addr_size = sizeof(client_addr); + err = recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0 , + (struct sockaddr*)&client_addr, (socklen_t *)&client_addr_size); + if(err < 0){ + MS_DBG("recvfrom error :%d", errno); + perror("recvfrom error : "); + goto NEXT; + } else { + MS_DBG("receive: %s\n", recv_buff); + } + + ret = ms_register_file(recv_buff, ret_queue); + if (ret == MS_ERR_NOW_REGISTER_FILE) { + MS_DBG("WAIT"); + ret= GPOINTER_TO_INT(g_async_queue_pop(ret_queue)) - MS_ERR_MAX; + MS_DBG("RECEIVE REPLAY"); + } + + if (ret != MS_ERR_NONE) { + MS_DBG("ms_register_file error : %d", ret); + + if(ret == MS_ERR_ARG_INVALID) { + send_msg = MS_MEDIA_ERR_INVALID_PARAMETER; + } else if (ret == MS_ERR_NOT_MEDIA_FILE) { + send_msg = MS_MEDIA_ERR_INVALID_MEDIA; + } else if (ret == MS_ERR_DB_INSERT_RECORD_FAIL) { + send_msg = MS_MEDIA_ERR_INSERT_FAIL; + } else if (ret == MS_ERR_DRM_REGISTER_FAIL) { + send_msg = MS_MEDIA_ERR_DRM_INSERT_FAIL; + } + } else { + MS_DBG("SOCKET INSERT SECCESS"); + send_msg = MS_MEDIA_ERR_NONE; + } + + err = sendto(sockfd, &send_msg, sizeof(send_msg), 0, + (struct sockaddr*)&client_addr, sizeof(client_addr)); + if(err < 0){ + MS_DBG("SOCKET SEND FAIL :%d", errno); + perror("send error : "); + } else { + MS_DBG("SOCKET SEND SUCCESS"); + } +NEXT: + memset(recv_buff, 0, MS_FILE_PATH_LEN_MAX); + } + + close(sockfd); + MS_DBG("END SOCKET THREAD"); + + err = ms_media_db_close(); + if (err != MS_ERR_NONE) { + MS_DBG("ms_media_db_close error : %d", err); + return false; + } + MS_DBG("Disconnect MEDIA DB"); + + return 0; +} + diff --git a/common/media-server-thumb.c b/common/media-server-thumb.c new file mode 100755 index 0000000..e2eeaad --- /dev/null +++ b/common/media-server-thumb.c @@ -0,0 +1,108 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-thumb.c + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ +#include <media-svc.h> +#include <media-thumbnail.h> +#include <vconf.h> + +#include "media-server-common.h" +#include "media-server-thumb.h" + +#ifdef THUMB_THREAD +extern int mmc_state; +extern int current_usb_mode; + +static int _ite_fn(Mitem * item, void *user_data) +{ + GList **list = (GList **) user_data; + *list = g_list_append(*list, item); + + return 0; +} + +gboolean ms_thumb_thread(void *data) +{ + int err = -1; + int i = 0; + Mitem *mitem = NULL; + GList *p_list = NULL; + minfo_item_filter item_filter; + char thumb_path[1024]; + + memset(&item_filter, 0x00, sizeof(minfo_item_filter)); + + item_filter.file_type = MINFO_ITEM_ALL; + item_filter.sort_type = MINFO_MEDIA_SORT_BY_DATE_ASC; + item_filter.start_pos = -1; + item_filter.end_pos = -1; + item_filter.with_meta = FALSE; + item_filter.favorite = MINFO_MEDIA_FAV_ALL; + + ms_media_db_open(); + + MS_DBG("data : %d", *(minfo_folder_type*)data); + + err = minfo_get_all_item_list(*(minfo_folder_type*)data, item_filter, _ite_fn, &p_list); + if (err < 0) { + MS_DBG("minfo_get_all_item_list error : %d", err); + return err; + } + + for (i = 0; i < g_list_length(p_list); i++) { + //check usb in out + if (current_usb_mode != VCONFKEY_USB_STORAGE_STATUS_OFF + || ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (*(minfo_folder_type*)data == MINFO_CLUSTER_TYPE_LOCAL_MMC))) { + MS_DBG("BREAK"); + break; + } + mitem = (Mitem *) g_list_nth_data(p_list, i); + + if (mitem) { + MS_DBG("Start to extracting thumbnails [%s] ( %s )", mitem->uuid, mitem->file_url); + err = minfo_extract_thumbnail(mitem->uuid, mitem->type); + if (err < 0) { + MS_DBG("thumbnail_request_from_db falied: %d", err); + } else { + MS_DBG("thumbnail_request_from_db success: %s", thumb_path); + } + + minfo_destroy_mtype_item(mitem); + } else { + MS_DBG("mitem[%d] is NULL", i); + } + } + + ms_media_db_close(); + + if (p_list != NULL) { + g_list_free(p_list); + p_list = NULL; + } +} +#endif |