diff options
author | Jiwoong Im <jiwoong.im@samsung.com> | 2015-10-01 15:57:18 +0900 |
---|---|---|
committer | Jiwoong Im <jiwoong.im@samsung.com> | 2015-10-07 00:23:08 -0700 |
commit | 5c4ef725ead2a88cdfa7cdc2331bfd8f42daf8fa (patch) | |
tree | 4706ec1330b499df6e8c9e8b7cfb2eac6812f37c | |
parent | 7850f88c8ca3c0e3290eabaa7ca0972ccf2c0fed (diff) | |
download | aul-1-5c4ef725ead2a88cdfa7cdc2331bfd8f42daf8fa.tar.gz aul-1-5c4ef725ead2a88cdfa7cdc2331bfd8f42daf8fa.tar.bz2 aul-1-5c4ef725ead2a88cdfa7cdc2331bfd8f42daf8fa.zip |
migrate appsvc to aulsubmit/tizen/20151012.020819
- sync with tizen 2.4
- add _with_uid api for multiuser architecture
- attach global db and create temp view in app_info db operation
- remove global .appsvc.db
TODO:
- implement aul_svc_request_transient_app
Change-Id: I697fb96278a583447c1b647453759fcaf93ce907
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | alias/alias.ini | 14 | ||||
-rw-r--r-- | include/aul.h | 182 | ||||
-rwxr-xr-x | include/aul_svc.h | 1098 | ||||
-rwxr-xr-x | include/aul_svc_db.h | 57 | ||||
-rwxr-xr-x | include/aul_svc_priv_key.h | 41 | ||||
-rw-r--r-- | packaging/aul.spec | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | src/service.c | 1337 | ||||
-rwxr-xr-x | src/service_db.c | 769 |
9 files changed, 3308 insertions, 200 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d531fc2..2b9968a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ ENDIF (with_x11) # Set required packages INCLUDE(FindPkgConfig) -SET(AUL-1_LIB_PKG_CHECK_MODULES dlog bundle dbus-glib-1 xdgmime libtzplatform-config pkgmgr-info libsystemd-daemon security-manager cynara-client cynara-creds-socket cynara-session capi-system-info vconf) +SET(AUL-1_LIB_PKG_CHECK_MODULES dlog bundle dbus-glib-1 xdgmime libtzplatform-config pkgmgr-info libsystemd-daemon security-manager cynara-client cynara-creds-socket cynara-session capi-system-info vconf sqlite3 iniparser) IF (with_wayland) pkg_check_modules(libpkgs REQUIRED ${AUL-1_LIB_PKG_CHECK_MODULES} wayland-client tizen-extension-client) ENDIF (with_wayland) @@ -62,6 +62,7 @@ add_library(aul SHARED src/launch_glib.c src/launch_with_result.c src/service.c + src/service_db.c src/mime.c src/miregex.c src/app_signal.c @@ -118,6 +119,7 @@ CONFIGURE_FILE(feature/preexec_list.txt.in feature/preexec_list.txt @ONLY) # Install headers, other files INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul.h DESTINATION include/aul) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_rsc_mgr.h DESTINATION include/aul) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/aul_svc.h DESTINATION include/aul) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/aul.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/legacy/preload_list.txt DESTINATION ${SHARE_INSTALL_PREFIX}/aul ) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/feature/preexec_list.txt DESTINATION ${SHARE_INSTALL_PREFIX}/aul ) diff --git a/alias/alias.ini b/alias/alias.ini new file mode 100644 index 00000000..20ec004b --- /dev/null +++ b/alias/alias.ini @@ -0,0 +1,14 @@ +# Alias +[Alias] +tizen.imageviewer=image-viewer-efl +tizen.internet=org.tizen.browser +tizen.phone=org.tizen.phone +tizen.filemanager=org.tizen.myfile +tizen.contacts=org.tizen.contacts +tizen.call=org.tizen.call +tizen.smsmessages=msg-composer-efl +tizen.mmsmessages=msg-composer-efl +tizen.messages=msg-composer-efl +tizen.email=org.tizen.email +tizen.calendar=org.tizen.calendar +tizen.camera=org.tizen.camera-app diff --git a/include/aul.h b/include/aul.h index 4422b5f1..64ae43d7 100644 --- a/include/aul.h +++ b/include/aul.h @@ -1305,109 +1305,6 @@ int aul_get_mime_extension(const char *mimetype, char *extlist, int len); */ int aul_get_mime_description(const char *mimetype, char *desc, int len); -/************************************************************************************************/ -/* Example of aul_open_content or aul_open_file */ -/* voice call , browser , docview , image viewer , audio player, video player */ -/* */ -/* voice call - aul_open_content("callto://011-1111-1111"); */ -/* browser - aul_open_content("http://www.naver.com"); */ -/* - aul_open_file("/opt/share/index.html"); */ -/* docview - aul_open_file("/opt/share/word.pdf"); */ -/* image view - aul_open_file("/opt/share/image.jpg"); */ -/* audio play - aul_open_file("/opt/share/audio.mp3"); */ -/* video play - aul_open_file("/opt/share/video.mpg"); */ -/************************************************************************************************/ - -/** @} */ - -/** - * @defgroup aul_service High-level APIs to launch applications based on service. - * @ingroup aul - * @brief - * AUL High-level APIs based on service - * - * This is Request/Response mechanism based on AUL like DBUS service call with auto-activation.\n - * We recommend this APIs for requesting application service like camera application service (take_picture) - * But, You can use other mechanism like DBUS service or your own internal IPC - * - * - Caller\n - * Launch application based on service \n - * If application is not running, AUL requests to reset the event.\n - * Application can wait result with callback function. - * - * - Callee\n - * After callee performs the requested operation, callee sends the result back, if necessary.\n - * - */ - -/** - * @addtogroup aul_service - * @{ - */ - -/** - * @brief aul_service_res_fn is service result function - * @param[out] b result bundle - * @param[out] data user-supplied data -*/ -typedef void (*aul_service_res_fn)(bundle *b, int reserved, void *user_data); - -/** - * @par Description: - * This API launch application based on service. - * @par Purpose: - * This API is for caller. - * This API launch application based on service name. - * This API find default application associated with service name. - * and then launch the application with given bundle. - * @par Typical use case: - * You can launch application provided the service if you know service name. - * That is, even if you don't know the specific application's pkgname, - * you can launch the applicaiton by requesting the service. - * For example, If you want to take a picture in your app, you can simply launch camera application. - * At that time, you can use this API like aul_open_service(TAKE_PICTURE_SVC,..); - * - * - * @param[in] svcname service name to launch as callee - * @param[in] b bundle to be passed to callee - * @param[in] cbfunc result callback function - * @param[in] data user-supplied data passed to callback function - * @return callee's pid if success, negative value(<0) if fail - * @retval AUL_R_OK - success - * @retval AUL_R_EINVAL - invaild service name - * @retval AUL_R_ENOINIT - you must initilize aul library with aul_launch_init - * @retval AUL_R_ECOM - internal AUL IPC error - * @retval AUL_R_ERROR - general error - * - * @pre - * None - * @post - * None - * @see - * None - * @code - * #include <aul.h> - * #include <aul_service.h> - * #include <bundle.h> - * - * void res_func(bundle *b, int reserved, void *user_data) - * { - * // process result bundle - * } - * - * int create_camera_view() - * { - * aul_open_service(TAKE_PICTURE_SVC, NULL, res_func, NULL); - * } - * - * @endcode - * @remark - * This API can wait result (asynchronous). - * To see kinds of default service provided by platform, see "aul_service.h" header file - * - */ -int aul_open_service(const char *svcname, bundle *b, aul_service_res_fn cbfunc, void *data); - /** * @par Description: * This API create service result bundle based on bundle received in reset event. @@ -1504,85 +1401,6 @@ int aul_send_service_result(bundle *b); /** * @par Description: - * This API set the default application(appid) associated with service name - * @par Purpose: - * This API use to change default application associteted with service name - * In general, Setting Application needs this API. - * @par Typical use case: - * Default Application associated with service name can be changed by Setting Application - * So, Inhouse service application can be substituted by 3rd party service application - * - * @param[in] svcname service string like "create_contact" - * @param[in] defapp default application like "com.samsung.contact" - * @return 0 if success, negative value if fail - * @retval AUL_R_OK - success - * @retval AUL_R_EINVAL - invalid argument(content) - * @retval AUL_R_ERROR - general error - * - * @pre - * None - * @post - * None - * @see - * aul_get_defapp_for_service - * @code - * #include <aul.h> - * #include <aul_service.h> - * - * void set_camera_service_defapp() - * { - * aul_set_defapp_for_service(TAKE_PICTURE_SVC,"com.samsung.camera"); - * } - * - * @endcode - * @remark - * None - * - */ -int aul_set_defapp_for_service(const char *svcname, const char *defapp); - -/** - * @par Description: - * This API get the application appid associated with given service name - * @par Purpose: - * This API use to get default application associteted with service name - * In general, Setting Application need this API. - * @par Typical use case: - * Setting Application show mapping of default application/ service - * - * @param[in] svcname service string like "create_contact" - * @param[out] defapp default application - * @param[in] len length of defapp - * @return 0 if success, negative value if fail - * @retval AUL_R_OK - success - * @retval AUL_R_EINVAL - invalid argument(content) - * @retval AUL_R_ERROR - general error - * - * @pre - * None - * @post - * None - * @see - * aul_set_defapp_for_service - * @code - * #include <aul.h> - * #include <aul_service.h> - * - * void get_camera_service_defapp() - * { - * char appname[255]; - * aul_get_defapp_for_service(TAKE_PICTURE_SVC,appname,sizeof(appname)); - * } - * - * @endcode - * @remark - * None - * - */ -int aul_get_defapp_for_service(const char *svcname, char *defapp, int len); - -/** - * @par Description: * This API sets callback fuction that will be called when applications die. * @par Purpose: * This API's purpose is to listen the application dead event. diff --git a/include/aul_svc.h b/include/aul_svc.h new file mode 100755 index 00000000..c008133a --- /dev/null +++ b/include/aul_svc.h @@ -0,0 +1,1098 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AUL_SVC_H__ +#define __AUL_SVC_H__ + +#include <bundle.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_DEFAULT "http://tizen.org/appcontrol/operation/default" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_EDIT "http://tizen.org/appcontrol/operation/edit" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_VIEW "http://tizen.org/appcontrol/operation/view" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_PICK "http://tizen.org/appcontrol/operation/pick" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_CREATE_CONTENT "http://tizen.org/appcontrol/operation/create_content" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_CALL "http://tizen.org/appcontrol/operation/call" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_SEND "http://tizen.org/appcontrol/operation/send" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_SEND_TEXT "http://tizen.org/appcontrol/operation/send_text" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_DIAL "http://tizen.org/appcontrol/operation/dial" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_SEARCH "http://tizen.org/appcontrol/operation/search" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_DOWNLOAD "http://tizen.org/appcontrol/operation/download" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_SHARE "http://tizen.org/appcontrol/operation/share" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_MULTI_SHARE "http://tizen.org/appcontrol/operation/multi_share" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_SHARE_TEXT "http://tizen.org/appcontrol/operation/share_text" +/** AUL_SVC_OPERATION_TYPE*/ +#define AUL_SVC_OPERATION_COMPOSE "http://tizen.org/appcontrol/operation/compose" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_LOCATION "http://tizen.org/appcontrol/operation/configure/location" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_FONT_TYPE "http://tizen.org/appcontrol/operation/configure/font/type" +/** AUL_SVC OPERATION TYPE*/ +#define AUL_SVC_OPERATION_FONT_SIZE "http://tizen.org/appcontrol/operation/configure/font/size" +#define AUL_SVC_OPERATION_LAUNCH_ON_EVENT "http://tizen.org/appcontrol/operation/launch_on_event" + + + +/** AUL_SVC DATA SUBJECT*/ +#define AUL_SVC_DATA_SUBJECT "http://tizen.org/appcontrol/data/subject" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_TO "http://tizen.org/appcontrol/data/to" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_CC "http://tizen.org/appcontrol/data/cc" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_BCC "http://tizen.org/appcontrol/data/bcc" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_TEXT "http://tizen.org/appcontrol/data/text" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_TITLE "http://tizen.org/appcontrol/data/title" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_SELECTED "http://tizen.org/appcontrol/data/selected" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_KEYWORD "http://tizen.org/appcontrol/data/keyword" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_PATH "http://tizen.org/appcontrol/data/path" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_SELECTION_MODE "http://tizen.org/appcontrol/data/selection_mode" +/** AUL_SVC DATA TYPE*/ +#define AUL_SVC_DATA_RETURN_RESULT "http://tizen.org/appcontrol/data/return_result" + + +/** AUL SVC internal private key */ +#define AUL_SVC_K_URI_R_INFO "__AUL_SVC_URI_R_INFO__" + +#define AUL_SVC_K_SELECTOR_EXTRA_LIST "http://tizen.org/appcontrol/data/selector_extra_list" + +#ifdef _APPFW_FEATURE_MULTI_INSTANCE +#define AUL_SVC_K_MULTI_INSTANCE "multi_instance" +#endif + +#define APP_SELECTOR "org.tizen.app-selector" +#define SHARE_PANEL "org.tizen.share-panel" + +/** Internal operation for launching application which is other zone */ +#define AUL_SVC_OPERATION_JUMP "http://tizen.org/appcontrol/operation/jump" +#define AUL_SVC_K_JUMP_ZONE_NAME "__K_JUMP_DOMAIN_NAME__" +#define AUL_SVC_K_JUMP_ORIGIN_OPERATION "__K_JUMP_ORIGIN_OPERATION__" +#define AUL_SVC_K_FOCUS_ZONE "__K_FOCUS_ZONE__" +#define AUL_SVC_K_LAUNCH_RESULT_APP_STARTED "__K_LAUNCH_RESULT_APP_STARTED__" +#define AUL_SVC_K_CAN_BE_LEADER "__K_CAN_BE_LEADER__" +#define AUL_SVC_K_REROUTE "__K_REROUTE__" +#define AUL_SVC_K_SHIFT_WINDOW "__K_SHIFT_WINDOW" +#define AUL_SVC_K_RECYCLE "__K_RECYCLE" + + +/** + * @brief Return values in appsvc. + */ +typedef enum _aul_svc_return_val { + AUL_SVC_RET_EREJECTED = -7, /**< application launch rejected */ + AUL_SVC_RET_ETERMINATING = -6, /**< application terminating */ + AUL_SVC_RET_EILLACC = -5, /**< Illegal Access */ + AUL_SVC_RET_ELAUNCH = -4, /**< Failure on launching the app */ + AUL_SVC_RET_ENOMATCH = -3, /**< No matching result Error */ + AUL_SVC_RET_EINVAL = -2, /**< Invalid argument */ + AUL_SVC_RET_ERROR = -1, /**< General error */ + AUL_SVC_RET_OK = 0 /**< General success */ +} aul_svc_return_val; + + +/** + * @brief result values in appsvc. + */ +typedef enum _aul_svc_result_val +{ + AUL_SVC_RES_CANCEL = -2, /**< Cancel by system */ + AUL_SVC_RES_NOT_OK = -1, /**< Fail by user */ + AUL_SVC_RES_OK = 0 /**< Success by user */ +} aul_svc_result_val; + + +/** + * @brief aul_svc_res_fn is appsvc result function + * @param[out] b result bundle + * @param[out] request_code request code + * @param[out] result result value + * @param[out] data user-supplied data +*/ +typedef void (*aul_svc_res_fn)(bundle *b, int request_code, aul_svc_result_val result, void *data); + + +/** + * @brief iterator function running with aul_svc_get_list + * @param[out] appid appid retreived by aul_svc_get_list + * @param[out] data user-supplied data +*/ +typedef int (*aul_svc_info_iter_fn)(const char *appid, void *data); + +typedef int (*aul_svc_host_res_fn)(void *data); + +/** + * @par Description: + * This function sets an operation to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] operation operation + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks An application must call this function before using aul_svc_run_service API. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_VIEW); +} + * @endcode + * + */ +int aul_svc_set_operation(bundle *b, const char *operation); + +/** + * @par Description: + * This function sets an uri to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] uri uri + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_VIEW); + aul_svc_set_uri(b,"http://www.samsung.com"); +} + * @endcode + * + */ +int aul_svc_set_uri(bundle *b, const char *uri); + +/** + * @par Description: + * This function sets a mime-type to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] mime mime-type + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_PICK); + aul_svc_set_mime(b,"image/jpg"); +} + * @endcode + * + */ +int aul_svc_set_mime(bundle *b, const char *mime); + +/** + * @par Description: + * This function sets an extra data to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] key key of extra data + * @param[in] val data + * + * @return 0 if success, negative value(<0) if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_SEND); + aul_svc_set_uri(b,"mailto:xxx1@xxx"); + aul_svc_add_data(b,AUL_SVC_DATA_CC,"xxx2@xxx"); +} + * @endcode + * + */ +int aul_svc_add_data(bundle *b, const char *key, const char *val); + +/** + * @par Description: + * This function sets an extra array data to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] key key of extra data + * @param[in] val_array data + * @param[in] len Length of array + * + * @return 0 if success, negative value(<0) if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + char *images[] = {"/opt/media/a.jpg", "/opt/media/b.jpg", "/opt/media/c.jpg"}; + + b = bundle_create(); + + aul_svc_add_data_array(b, AUL_SVC_DATA_SELECTED, images, 3); +} + * @endcode + * + */ +int aul_svc_add_data_array(bundle *b, const char *key, const char **val_array, int len); + + +/** + * @par Description: + * This function sets a package name to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] pkg_name package name for explict launch + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_PICK); + aul_svc_set_mime(b,"image/jpg"); + aul_svc_set_pkgname(b, "org.tizen.mygallery"); +} + * @endcode + * + */ +/* Deprecated API */ +int aul_svc_set_pkgname(bundle *b, const char *pkg_name); // __attribute__((deprecated)); + + +/** + * @par Description: + * This function sets a appid to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] appid application id for explict launch + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_PICK); + aul_svc_set_mime(b,"image/jpg"); + aul_svc_set_appid(b, "org.tizen.mygallery"); +} + * @endcode + * + */ +int aul_svc_set_appid(bundle *b, const char *appid); + + +/** + * @par Description: + * This function sets a appid to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] application category + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_VIEW); + aul_svc_set_category(b, "http://tizen.org/category/app/browser"); +} + * @endcode + * + */ +int aul_svc_set_category(bundle *b, const char *category); + +/** + * @par Description: + * This API launch application based on appsvc. + * + * @param[in] b bundle to be passed to callee + * @param[in] request_code request code + * @param[in] cbfunc result callback function + * @param[in] data user-supplied data passed to callback function + * + * @return callee's pid if success, negative value(<0) if fail + * @retval callee's pid - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * @retval AUL_SVC_RET_ENOMATCH - no matching result Error + * @retval AUL_SVC_RET_ELAUNCH - failure on launching the app + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + bundle *b = NULL; + static int num = 0; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_PICK); + aul_svc_set_mime(b,"image/jpg"); + + return aul_svc_run_service(b, 0, cb_func, (void*)NULL); +} + * @endcode + * + */ +int aul_svc_run_service(bundle *b, int request_code, aul_svc_res_fn cbfunc, void *data); +int aul_svc_run_service_with_uid(bundle *b, int request_code, + aul_svc_res_fn cbfunc, void *data, uid_t uid); + +/** + * @par Description: + * This API use to get application list that is matched with given bundle. + * + * @param[in] b bundle to resolve application + * @param[in] iter_fn iterator function + * @param[in] data user-supplied data for iter_fn + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * @retval AUL_SVC_RET_ENOMATCH - no matching result Error + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +static int iter_fn(const char* appid, void *data) +{ + printf("\t==========================\n"); + printf("\t appid: %s\n", appid); + printf("\t==========================\n"); + return 0; +} + +... +{ + bundle *b = NULL; + static int num = 0; + + b = bundle_create(); + + aul_svc_set_operation(b, AUL_SVC_OPERATION_PICK); + aul_svc_set_mime(b,"image/jpg"); + + return aul_svc_get_list(b, iter_fn, (void*)NULL); +} + * @endcode + * + */ +int aul_svc_get_list(bundle *b, aul_svc_info_iter_fn iter_fn, void *data); +int aul_svc_get_list_with_uid(bundle *b, aul_svc_info_iter_fn iter_fn, + void *data, uid_t uid); + +/** + * @par Description: + * This API use to get default applications + * + * @param[in] iter_fn iterator function + * @param[in] data user-supplied data for iter_fn + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * @retval AUL_SVC_RET_ENOMATCH - no matching result Error + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +static int iter_fn(const char* appid, void *data) +{ + printf("\t==========================\n"); + printf("\t appid : %s\n", appid); + printf("\t==========================\n"); + return 0; +} + +... +{ + return aul_svc_get_all_defapps(iter_fn, (void*)NULL); +} + * @endcode + * + */ +int aul_svc_get_all_defapps(aul_svc_info_iter_fn iter_fn, void *data); +int aul_svc_get_all_defapps_with_uid(aul_svc_info_iter_fn iter_fn, + void *data, uid_t uid); + +/** + * @par Description: + * This function gets a operation from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for operation string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_operation(b); +} + * @endcode + * + */ +const char *aul_svc_get_operation(bundle *b); + +/** + * @par Description: + * This function gets a uri from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for uri string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_uri(b); +} + * @endcode + * + */ +const char *aul_svc_get_uri(bundle *b); + +/** + * @par Description: + * This function gets a mime-type from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for mime-type string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_mime(b); +} + * @endcode + * + */ +const char *aul_svc_get_mime(bundle *b); + +/** + * @par Description: + * This function gets a package name from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for package name string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_pkgname(b); +} + * @endcode + * + */ +/* Deprecated API */ +const char *aul_svc_get_pkgname(bundle *b); // __attribute__((deprecated)); + +/** + * @par Description: + * This function gets a application id from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for application id string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_appid(b); +} + * @endcode + * + */ +const char *aul_svc_get_appid(bundle *b); + +/** + * @par Description: + * This function gets a application category from bundle. + * + * @param[in] b bundle object + * + * @return Pointer for application category string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_category(b); +} + * @endcode + * + */ +const char *aul_svc_get_category(bundle *b); + +/** + * @par Description: + * This function gets value from key. + * + * @param[in] b bundle object + * @param[in] key key + * + * @return Pointer for value string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char *val; + val = aul_svc_get_data(b, AUL_SVC_DATA_CC); +} + * @endcode + * + */ +const char *aul_svc_get_data(bundle *b, const char *key); + +/** + * @par Description: + * This function gets value from key. + * + * @param[in] b bundle object + * @param[in] key key + * @param[out] len length of array + * + * @return Pointer for value string array if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + char **val_array; + int len; + char *val; + + if(aul_svc_data_is_array(b, AUL_SVC_DATA_SELECTED)) + val_array = aul_svc_get_data_array(b, AUL_SVC_DATA_SELECTED, &len); + else + val = aul_svc_get_data(b, AUL_SVC_DATA_SELECTED); +} + * @endcode + * + */ +const char **aul_svc_get_data_array(bundle *b, const char *key, int *len); + +/** + * @par Description: + * This API create appsvc result bundle based on bundle received in reset event. + * + * @param[in] inb bundle received in reset event + * @param[in] outb bundle to use for returning result + * + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see aul_svc_send_result. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + struct appdata *ad = data; + bundle* res_bundle; + + aul_svc_create_result_bundle(ad->b,&res_bundle); + bundle_add(res_bundle, "result", "1"); + aul_svc_send_result(res_bundle, 0); +} + * @endcode + * + */ +int aul_svc_create_result_bundle(bundle *inb, bundle **outb); + +/** + * @par Description: + * This API send appsvc result to caller with bundle. + * + * @param[in] b Result data in bundle format + * @param[in] result result value + * + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre aul_svc_create_result_bundle. + * @post None. + * @see aul_svc_send_result. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + struct appdata *ad = data; + bundle* res_bundle; + + aul_svc_create_result_bundle(ad->b,&res_bundle); + bundle_add(res_bundle, "result", "1"); + aul_svc_send_result(res_bundle, 0); +} + * @endcode + * + */ +int aul_svc_send_result(bundle *b, aul_svc_result_val result); + +/** + * @par Description: + * This API set the default application(package name) associated with op, uri and mime-type. + * + * @param[in] op operation + * @param[in] mime_type mime-type + * @param[in] scheme scheme of uri + * @param[in] defapp default application + * + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + aul_svc_set_defapp(AUL_SVC_OPERATION_VIEW, NULL,"http", "org.tizen.mybrowser"); +} + * @endcode + * + */ +int aul_svc_set_defapp(const char *op, const char *mime_type, const char *uri, + const char *defapp); +int aul_svc_set_defapp_with_uid(const char *op, const char *mime_type, const char *uri, + const char *defapp, uid_t uid); + +/** + * @par Description: + * This API unset the default application(package name) associated with op, uri and mime-type. + * + * @param[in] defapp default application + * + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + aul_svc_unset_defapp("org.tizen.test"); +} + * @endcode + * + */ +int aul_svc_unset_defapp(const char *defapp); +int aul_svc_unset_defapp_with_uid(const char *defapp, uid_t uid); + +/** + * @par Description: + * This API unset all of default applications associated with op, uri and mime-type. + * + * + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + aul_svc_unset_all_defapps(); +} + * @endcode + * + */ +int aul_svc_unset_all_defapps(); +int aul_svc_unset_all_defapps_with_uid(uid_t uid); + +/** + * @par Description: + * This API ask a application is default application or not. + * + * @param[in] appid application appid + * @return true / false + * @retval 1 app_name is default application in appsvc. + * @retval 0 app_name is NOT default application in appsvc. + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + + ... + + * int is_defapp_browser_app() + * { + * return aul_svc_is_defapp("org.tizen.browser"); + * } + * + * @endcode + * @remark + * None +* +*/ +int aul_svc_is_defapp(const char *appid); +int aul_svc_is_defapp_with_uid(const char *pkg_name, uid_t uid); + + +/** + * @par Description: + * This API ask a extra data is array or not. + * + * @param[in] b bundle object + * @param[in] key key of extra data + * @return true / false + * @retval 1 a extra data is array. + * @retval 0 a extra data is not array. + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + + ... + + * int aul_svc_data_is_array(bundle *b, char *key) + * { + * return aul_svc_data_is_array(b, key); + * } + * + * @endcode + * @remark + * None +* +*/ +int aul_svc_data_is_array(bundle *b, const char *key); + +int aul_svc_subapp_terminate_request_pid(int pid); + +/** + * @par Description: + * This function sets an uri to launch application based on appsvc. + * + * @param[in] b bundle object + * @param[in] char *mode + * + * @return 0 if success, negative value(<0) if fail + * @retval AUL_SVC_RET_OK - success + * @retval AUL_SVC_RET_ERROR - general error + * @retval AUL_SVC_RET_EINVAL - invalid argument(content) + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + aul_svc_set_launch_mode(app_control->data, mode); +} + * @endcode + * + */ +int aul_svc_set_launch_mode(bundle *b, const char *mode); + +/** + * @par Description: + * This function sets an uri to launch application based on appsvc. + * + * @param[in] b bundle object + * + * @return Pointer for launch mode string if success, NULL if fail + * + * @pre None. + * @post None. + * @see None. + * @remarks None. + * + * @par Sample code: + * @code +#include <aul_svc.h> + +... +{ + aul_svc_get_launch_mode(app_control->data); +} + * @endcode + * + */ +const char *aul_svc_get_launch_mode(bundle *b); + +int aul_svc_allow_transient_app(bundle *b, int wid); + +int aul_svc_request_transient_app(bundle *b, int callee_wid, + aul_svc_host_res_fn cbfunc, void *data); + +int aul_svc_subscribe_launch_result(bundle *b, const char *event); + +#ifdef __cplusplus +} +#endif + + +#endif /* __AUL_SVC_H__ */ + diff --git a/include/aul_svc_db.h b/include/aul_svc_db.h new file mode 100755 index 00000000..3494673d --- /dev/null +++ b/include/aul_svc_db.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __AUL_SVC_DB_H__ +#define __AUL_SVC_DB_H__ + +#include <sqlite3.h> +#include <time.h> +#include <sys/types.h> +#include <glib.h> + +#define MAX_FILTER_STR_SIZE 1024 +#define MAX_PACKAGE_STR_SIZE 512 +#define MAX_URI_STR_SIZE 256 +#define MAX_MIME_STR_SIZE 256 +#define MAX_SCHEME_STR_SIZE 256 +#define MAX_HOST_STR_SIZE 256 +#define MAX_OP_STR_SIZE 128 + +#ifdef __cplusplus +extern "C" +{ +#endif + +int _svc_db_check_perm(uid_t uid); +int _svc_db_add_app(const char *op, const char *mime_type, const char *uri, const char *pkg_name, uid_t uid); +int _svc_db_delete_with_pkgname(const char *pkg_name, uid_t uid); +char* _svc_db_get_app(const char *op, const char *mime_type, const char *uri, uid_t uid); +int _svc_db_is_defapp(const char *pkg_name, uid_t uid); +int _svc_db_adjust_list_with_submode(int mainapp_mode, char *win_id, GSList **pkg_list, uid_t uid); +int _svc_db_get_list_with_condition(char *op, char *uri, char *mime, GSList **pkg_list, uid_t uid); +int _svc_db_get_list_with_collation(char *op, char *uri, char *mime, GSList **pkg_list, uid_t uid); +int _svc_db_get_list_with_all_defapps(GSList **pkg_list, uid_t uid); +int _svc_db_delete_all(uid_t uid); + + + +#ifdef __cplusplus +} +#endif + +#endif /* __AUL_SVC_DB_H__ */ + diff --git a/include/aul_svc_priv_key.h b/include/aul_svc_priv_key.h new file mode 100755 index 00000000..38712aa4 --- /dev/null +++ b/include/aul_svc_priv_key.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __PRIV_KEY_H__ +#define __PRIV_KEY_H__ + +/** AUL SVC internal private key */ +#define AUL_SVC_K_OPERATION "__APP_SVC_OP_TYPE__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_URI "__APP_SVC_URI__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_MIME "__APP_SVC_MIME_TYPE__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_DATA "__APP_SVC_DATA__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_PKG_NAME "__APP_SVC_PKG_NAME__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_CATEGORY "__APP_SVC_CATEGORY__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_RES_VAL "__APP_SVC_K_RES_VAL__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_WIN_ID "__APP_SVC_K_WIN_ID__" +/** AUL SVC internal private key */ +#define AUL_SVC_K_LAUNCH_MODE "__APP_SVC_LAUNCH_MODE__" + +#endif /* __PRIV_KEY_H__ */ + diff --git a/packaging/aul.spec b/packaging/aul.spec index fe26de7e..de182d5f 100644 --- a/packaging/aul.spec +++ b/packaging/aul.spec @@ -39,6 +39,8 @@ BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-creds-socket) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(sqlite3) %if %{with wayland} BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(tizen-extension-client) @@ -101,6 +103,9 @@ ln -sf ../ac.service %{buildroot}%{_unitdir_user}/default.target.wants/ac.servic ln -sf ../ac.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/ac.socket ln -sf ../amd_session_agent.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/amd_session_agent.socket +mkdir -p %{buildroot}%{_datadir}/appsvc +cp -R %{_builddir}/%{name}-%{version}/alias/* %{buildroot}%{_datadir}/appsvc + %preun if [ $1 == 0 ]; then systemctl stop ac.service @@ -129,6 +134,7 @@ systemctl daemon-reload %{_datadir}/aul/miregex/* %{_datadir}/aul/preload_list.txt %{_datadir}/aul/preexec_list.txt +%{_datadir}/appsvc/* %{_tmpfilesdir}/ac.conf %{_unitdir_user}/ac.service %{_unitdir_user}/default.target.wants/ac.service diff --git a/src/service.c b/src/service.c index 3748a886..011b6180 100644..100755 --- a/src/service.c +++ b/src/service.c @@ -1,52 +1,1355 @@ /* - * aul + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com> - * - * Licensed under the Apache License, Version 2.0 (the "License"); + * 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, + * 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. - * */ +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #include <bundle.h> - +#include <bundle_internal.h> +#include <glib.h> +#include <string.h> +#include <pthread.h> +#include <dlfcn.h> +#include <iniparser.h> +#include <pkgmgr-info.h> #include "aul.h" #include "aul_api.h" +#include "aul_svc.h" +#include "aul_svc_db.h" +#include "simple_util.h" +#include "aul_svc_priv_key.h" #include "launch.h" -SLPAPI int aul_set_defapp_for_service(const char *svcname, const char *defapp) +/* callback handling */ +typedef struct _aul_svc_cb_info_t { + aul_svc_res_fn cb_func; + int request_code; + void *data; +} aul_svc_cb_info_t; + +typedef struct _aul_svc_resolve_info_t { + char *pkgname; + char *op; + char *uri; + char *scheme; + char *host; + char *uri_r_info; + char *origin_mime; + char *mime; + char *m_type; + char *s_type; + char *category; + char *win_id; + int mime_set; +} aul_svc_resolve_info_t; + +typedef struct _aul_svc_transient_cb_info_t { + aul_svc_host_res_fn cb_func; + void *data; +} aul_svc_transient_cb_info_t; + +pthread_mutex_t iniparser_lock = PTHREAD_MUTEX_INITIALIZER; +GSList *tmp_list; + +static aul_svc_cb_info_t *__create_rescb(int request_code, + aul_svc_res_fn cbfunc, + void *data); +static void __remove_rescb(aul_svc_cb_info_t *info); +static int __set_bundle(bundle *b, const char *key, const char *value); +static void __aul_cb(bundle *b, int is_cancel, void *data); +static int __run_svc_with_pkgname(char *pkgname, bundle *b, int request_code, + aul_svc_res_fn cbfunc, void *data); +static int __get_resolve_info(bundle *b, aul_svc_resolve_info_t *info); +static int __free_resolve_info_data(aul_svc_resolve_info_t *info); + +static char *white_list[] = { + APP_SELECTOR, + SHARE_PANEL, + NULL +}; + +static bool __is_special_app(const char *appid) +{ + const char *id; + int i = 0; + + if (appid == NULL) + return false; + + while ((id = white_list[i]) != NULL) { + if (strcmp(id, appid) == 0) + return true; + i++; + } + return false; +} + +static aul_svc_cb_info_t *__create_rescb(int request_code, + aul_svc_res_fn cbfunc, + void *data) +{ + aul_svc_cb_info_t* info; + + info = (aul_svc_cb_info_t*)calloc(1, sizeof(aul_svc_cb_info_t)); + if (info == NULL) + return NULL; + + info->request_code = request_code; + info->cb_func = cbfunc; + info->data = data; + + return info; +} + +static void __remove_rescb(aul_svc_cb_info_t *info) +{ + if (info) free(info); +} + +static int __set_bundle(bundle *b, const char *key, const char *value) { - /* removed */ + const char *val = NULL; + + val = bundle_get_val(b, key); + if (val) { + if ( bundle_del(b, key) != 0 ) { + return AUL_SVC_RET_ERROR; + } + } + + if (!value) + return AUL_SVC_RET_EINVAL; + + if ( bundle_add(b, key, value) != 0 ) { + return AUL_SVC_RET_ERROR; + } + + _D("__set_bundle"); + + return AUL_SVC_RET_OK; +} + +static int __set_bundle_array(bundle *b, const char *key, const char **value, + int len) +{ + + int type; + type = aul_svc_data_is_array(b, key); + + if (type == 1) { + if ( bundle_del(b, key) != 0 ) { + return AUL_SVC_RET_ERROR; + } + } + + if (!value) + return AUL_SVC_RET_EINVAL; + + if ( bundle_add_str_array(b, key, value, len) != 0 ) { + return AUL_SVC_RET_ERROR; + } + + _D("__set_bundle_array"); + + return AUL_SVC_RET_OK; +} + +static void __aul_cb(bundle *b, int is_cancel, void *data) +{ + const char *val = NULL; + aul_svc_cb_info_t* cb_info; + int res; + + if (is_cancel) + res = AUL_SVC_RES_CANCEL; + else { + /* get result_code from bundle */ + val = bundle_get_val(b, AUL_SVC_K_RES_VAL); + res = (val == NULL) ? AUL_SVC_RES_NOT_OK : atoi(val); + } + + /* remove result_code from bundle */ + bundle_del(b, AUL_SVC_K_RES_VAL); + + /* find corresponding callback */ + cb_info = (aul_svc_cb_info_t*)data; + + cb_info->cb_func(b, cb_info->request_code, (aul_svc_result_val)res, + cb_info->data); + __remove_rescb(cb_info); + + + return; +} + +static int __run_svc_with_pkgname(char *pkgname, bundle *b, int request_code, + aul_svc_res_fn cbfunc, void *data) +{ + aul_svc_cb_info_t *cb_info = NULL; + int ret = -1; + + if ( bundle_get_type(b, AUL_SVC_K_SELECTOR_EXTRA_LIST) != BUNDLE_TYPE_NONE ) { + if ( !aul_svc_get_pkgname(b) ) { + pkgname = APP_SELECTOR; + } + } + + if ( bundle_get_val(b, AUL_K_FORCE_LAUNCH_APP_SELECTOR) ) { + pkgname = APP_SELECTOR; + } + + if ( __is_special_app(pkgname)) { + bundle_del(b, AUL_SVC_K_CAN_BE_LEADER); + bundle_add_str(b, AUL_SVC_K_CAN_BE_LEADER, "true"); + bundle_del(b, AUL_SVC_K_REROUTE); + bundle_add_str(b, AUL_SVC_K_REROUTE, "true"); + bundle_del(b, AUL_SVC_K_RECYCLE); + bundle_add_str(b, AUL_SVC_K_RECYCLE, "true"); + + } + + if (cbfunc) { + SECURE_LOGD("pkg_name : %s - with result", pkgname); + + cb_info = __create_rescb(request_code, cbfunc, data); + ret = aul_launch_app_with_result(pkgname, b, __aul_cb, cb_info); + } else { + SECURE_LOGD("pkg_name : %s - no result", pkgname); + +#ifdef _APPFW_FEATURE_MULTI_INSTANCE + const char* data = bundle_get_val(b, AUL_SVC_K_MULTI_INSTANCE); + if (data) { + SECURE_LOGD("multi_instance value = %s", data); + } + + if (data && strncmp(data, "TRUE", strlen("TRUE")) == 0) { + ret = aul_launch_app_for_multi_instance(pkgname, b); + } else { + ret = aul_launch_app(pkgname, b); + } +#else + ret = aul_launch_app(pkgname, b); +#endif + } + + if (ret < 0) { + switch (ret) { + case AUL_R_EILLACC: + ret = AUL_SVC_RET_EILLACC; + break; + case AUL_R_EINVAL: + ret = AUL_SVC_RET_EINVAL; + break; + case AUL_R_ETERMINATING: + ret = AUL_SVC_RET_ETERMINATING; + break; + case AUL_R_EREJECTED: + ret = AUL_SVC_RET_EREJECTED; + break; + case AUL_R_ENOAPP: + ret = AUL_SVC_RET_ENOMATCH; + break; + default: + ret = AUL_SVC_RET_ELAUNCH; + } + } + + return ret; +} + +static int __get_resolve_info(bundle *b, aul_svc_resolve_info_t *info) +{ + char *tmp = NULL; + char *strtok_buf = NULL; + int ret = -1; + + info->op = (char *)aul_svc_get_operation(b); + info->uri = (char *)aul_svc_get_uri(b); + + if ((info->uri) && (strcmp(info->uri, "") == 0)) { + _E("Uri is empty"); + return AUL_SVC_RET_EINVAL; + } + + info->origin_mime = info->mime = (char *)aul_svc_get_mime(b); + info->pkgname = (char *)aul_svc_get_pkgname(b); + info->category = (char *)aul_svc_get_category(b); + info->win_id = (char *)bundle_get_val(b, AUL_SVC_K_WIN_ID); + + _D("getting resolve info for: operation - %s / uri - %s / mime - %s\n", + info->op, info->uri, info->mime); + + if (info->uri) { + if (strncmp(info->uri, "/", 1) == 0) { + if (!info->mime) { + info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE); + if (info->mime == NULL) { + _E("out of memory"); + return AUL_SVC_RET_ERROR; + } + + ret = aul_get_mime_from_file(info->uri, info->mime, MAX_MIME_STR_SIZE); + info->mime_set = 1; + } + info->uri = NULL; + } else if (strncmp(info->uri, "file:///", 8) == 0) { + if (!info->mime) { + info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE); + if (info->mime == NULL) { + _E("out of memory"); + return AUL_SVC_RET_ERROR; + } + + ret = aul_get_mime_from_file(&info->uri[7], info->mime, MAX_MIME_STR_SIZE); + info->mime_set = 1; + } + } else if (strncmp(info->uri, "file:/", 6) == 0) { + if (!info->mime) { + info->origin_mime = info->mime = malloc(MAX_MIME_STR_SIZE); + if (info->mime == NULL) { + _E("out of memory"); + return AUL_SVC_RET_ERROR; + } + + ret = aul_get_mime_from_file(&info->uri[5], info->mime, MAX_MIME_STR_SIZE); + info->mime_set = 1; + } + } + + if (info->mime_set == 1 && ret < 0) { + _E("aul_get_mime_from_file : %d", ret); + free(info->mime); + info->origin_mime = info->mime = NULL; + info->mime_set = 0; + } + } + + if (info->uri) { + GRegex *regex; + GMatchInfo *match_info; + GError *error = NULL; + + regex = g_regex_new ("^(([^:/?#]+):)?(//([^/?#]*))?", 0, 0, &error); + if (g_regex_match (regex, info->uri, 0, &match_info) == FALSE) { + g_regex_unref (regex); + return AUL_SVC_RET_EINVAL; + } + + info->scheme = g_match_info_fetch (match_info, 2); + info->host = g_match_info_fetch (match_info, 4); + + if (info->scheme && info->host) { + info->uri_r_info = malloc(MAX_SCHEME_STR_SIZE + MAX_HOST_STR_SIZE + 2); + if (info->uri_r_info == NULL) { + _E("out of memory"); + g_match_info_free(match_info); + g_regex_unref(regex); + return AUL_SVC_RET_ERROR; + } + + snprintf(info->uri_r_info, MAX_SCHEME_STR_SIZE + MAX_HOST_STR_SIZE + 1, + "%s://%s", info->scheme, info->host); + } + + g_match_info_free (match_info); + g_regex_unref (regex); + + } else { + info->scheme = strdup("NULL"); + } + + if (!info->mime) + info->mime = strdup("NULL"); + else { + info->m_type = malloc(MAX_LOCAL_BUFSZ); + if (info->m_type == NULL) { + _E("ouf of memory"); + return AUL_SVC_RET_ERROR; + } + + info->s_type = malloc(MAX_LOCAL_BUFSZ); + if (info->s_type == NULL) { + _E("out of memory"); + free(info->m_type); + return AUL_SVC_RET_ERROR; + } + + tmp = strdup(info->mime); + strtok_buf = strtok(tmp, "/"); + if (strtok_buf) + strncpy(info->m_type, strtok_buf, MAX_LOCAL_BUFSZ - 1); + strtok_buf = strtok(NULL, "/"); + if (strtok_buf) + strncpy(info->s_type, strtok_buf, MAX_LOCAL_BUFSZ - 1); + free(tmp); + + if (strncmp(info->m_type, "*", 1) == 0) { + strncpy(info->m_type, "%", MAX_LOCAL_BUFSZ - 1); + } + if (strncmp(info->s_type, "*", 1) == 0) { + strncpy(info->s_type, "%", MAX_LOCAL_BUFSZ - 1); + } + + info->mime = malloc(MAX_MIME_STR_SIZE); + if (info->mime == NULL) { + _E("out of memory"); + free(info->s_type); + free(info->m_type); + return AUL_SVC_RET_ERROR; + } + + snprintf(info->mime, MAX_MIME_STR_SIZE - 1, "%s/%s", info->m_type, + info->s_type); + } + return 0; } -SLPAPI int aul_get_defapp_for_service(const char *svcname, char *defapp, - int len) +static int __free_resolve_info_data(aul_svc_resolve_info_t *info) { - /* removed */ + if (info->mime) + free(info->mime); + if (info->scheme) + free(info->scheme); + if (info->host) + free(info->host); + if (info->m_type) + free(info->m_type); + if (info->s_type) + free(info->s_type); + if (info->uri_r_info) + free(info->uri_r_info); + if (info->mime_set) + free(info->origin_mime); + return 0; } -SLPAPI int aul_open_service(const char *svcname, bundle *kb, - aul_service_res_fn cbfunc, void *userdata) +static char* __get_alias_appid(char *appid) { - /* removed */ + char *alias_id = NULL; + char *val = NULL; + char key_string[MAX_PACKAGE_STR_SIZE + 5]; + dictionary *dic; + + dic = iniparser_load("/usr/share/appsvc/alias.ini"); + + if (dic == NULL) + return NULL; + + snprintf(key_string, sizeof(key_string), "Alias:%s", appid); + pthread_mutex_lock(&iniparser_lock); + val = iniparser_getstring(dic, key_string, NULL); + pthread_mutex_unlock(&iniparser_lock); + + SECURE_LOGD("alias_id : %s", val); + + if (val != NULL) { + alias_id = malloc(MAX_PACKAGE_STR_SIZE); + if (alias_id == NULL) { + _E("out of memory"); + iniparser_freedict(dic); + return NULL; + } + + strncpy(alias_id, val, MAX_PACKAGE_STR_SIZE - 1); + } + + iniparser_freedict(dic); + + return alias_id; +} + +static int __get_list_with_condition_mime_extened(char *op, char *uri, + char *mime, char *m_type, char *s_type, GSList **pkg_list, uid_t uid) +{ + char *tmp; + + tmp = malloc(MAX_MIME_STR_SIZE); + if (tmp == NULL) { + _E("out of memory"); + return -1; + } + + _svc_db_get_list_with_condition(op, uri, mime, pkg_list, uid); + if ((strncmp(mime, "NULL", 4) != 0) && (strncmp(s_type, "%", 1) != 0)) { + snprintf(tmp, MAX_MIME_STR_SIZE - 1, "%s/*", m_type); + _svc_db_get_list_with_condition(op, uri, tmp, pkg_list, uid); + } + if ((strncmp(mime, "NULL", 4) != 0) && (strncmp(m_type, "%", 1) != 0)) { + snprintf(tmp, MAX_MIME_STR_SIZE - 1, "*/*"); + _svc_db_get_list_with_condition(op, uri, tmp, pkg_list, uid); + } + + free(tmp); + + return 0; +} + +static int __get_list_with_condition_mime_extened_with_collation(char *op, + char *uri, char *mime, char *m_type, char *s_type, GSList **pkg_list, uid_t uid) +{ + char *tmp; + + tmp = malloc(MAX_MIME_STR_SIZE); + if (tmp == NULL) { + _E("out of memory"); + return -1; + } + + _svc_db_get_list_with_collation(op, uri, mime, pkg_list, uid); + if ((strncmp(mime, "NULL", 4) != 0) && (strncmp(s_type, "%", 1) != 0)) { + snprintf(tmp, MAX_MIME_STR_SIZE - 1, "%s/*", m_type); + _svc_db_get_list_with_collation(op, uri, tmp, pkg_list, uid); + } + if ((strncmp(mime, "NULL", 4) != 0) && (strncmp(m_type, "%", 1) != 0)) { + snprintf(tmp, MAX_MIME_STR_SIZE - 1, "*/*"); + _svc_db_get_list_with_collation(op, uri, tmp, pkg_list, uid); + } + + free(tmp); + + return 0; +} + + +static int __app_list_cb(pkgmgrinfo_appinfo_h handle, void *user_data) +{ + char *appid = NULL; + GSList **app_list = (GSList **)user_data; + char *str = NULL; + GSList *iter = NULL; + + pkgmgrinfo_appinfo_get_appid(handle, &str); + _D("Matching application is %s", str); + + for (iter = tmp_list; iter != NULL; iter = g_slist_next(iter)) { + if (strncmp(str, (char *)iter->data, MAX_PACKAGE_STR_SIZE - 1) == 0) { + appid = strdup(str); + *app_list = g_slist_append(*app_list, (void *)appid); + _D("%s is added", appid); + } + } + + return 0; +} + +static int __get_list_with_category(char *category, GSList **pkg_list, uid_t uid) +{ + int ret; + pkgmgrinfo_appinfo_filter_h handle; + GSList *app_list = NULL; + GSList *iter = NULL; + char *list_item = NULL; + + ret = pkgmgrinfo_appinfo_filter_create(&handle); + ret = pkgmgrinfo_appinfo_filter_add_string(handle, + PMINFO_APPINFO_PROP_APP_CATEGORY, category); + + tmp_list = *pkg_list; + ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, __app_list_cb, + &app_list, uid); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_filter_destroy(handle); + return -1; + } + pkgmgrinfo_appinfo_filter_destroy(handle); + + for (iter = *pkg_list; iter != NULL; iter = g_slist_next(iter)) { + list_item = (char *)iter->data; + g_free(list_item); + } + g_slist_free(*pkg_list); + + *pkg_list = app_list; + + return 0; +} + +static int __appid_compare(gconstpointer data1, gconstpointer data2) +{ + char *a = (char *)data1; + char *b = (char *)data2; + return strcmp(a, b); +} + +static int __check_mainapp_mode(char *operation) +{ + return 0; +} + +static int __get_list_with_submode(char *operation, char *win_id, + GSList **pkg_list, uid_t uid) +{ + int ret = 0; + int mainapp_mode = 0; + + mainapp_mode = __check_mainapp_mode(operation); + + SECURE_LOGD("mainapp_mode : %d", mainapp_mode); + + ret = _svc_db_adjust_list_with_submode(mainapp_mode, win_id, pkg_list, uid); + + if (ret < 0) { + _E("error on get_list_with_submode :%d", ret); + return -1; + } + return 0; } +SLPAPI int aul_svc_set_operation(bundle *b, const char *operation) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_operation is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_OPERATION, operation); +} + +SLPAPI int aul_svc_set_uri(bundle *b, const char *uri) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_uri is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_URI, uri); +} + +SLPAPI int aul_svc_set_mime(bundle *b, const char *mime) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_mime is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_MIME, mime); +} + +SLPAPI int aul_svc_add_data(bundle *b, const char *key, const char *val) +{ + if (b == NULL || key == NULL) { + return AUL_SVC_RET_EINVAL; + } + + /* check key for data */ + /******************/ + + return __set_bundle(b, key, val); +} + +SLPAPI int aul_svc_add_data_array(bundle *b, const char *key, + const char **val_array, int len) +{ + if (b == NULL || key == NULL) { + return AUL_SVC_RET_EINVAL; + } + + /* check key for data */ + /******************/ + + return __set_bundle_array(b, key, val_array, len); +} + + +SLPAPI int aul_svc_set_pkgname(bundle *b, const char *pkg_name) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_pkgname is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_PKG_NAME, pkg_name); +} + + +SLPAPI int aul_svc_set_appid(bundle *b, const char *appid) +{ + char *alias_id = NULL; + int ret; + + if (b == NULL || appid == NULL) { + _E("bundle for aul_svc_set_appid is NULL"); + return AUL_SVC_RET_EINVAL; + } + + alias_id = __get_alias_appid((char *)appid); + if (alias_id == NULL) { + ret = __set_bundle(b, AUL_SVC_K_PKG_NAME, appid); + } else { + ret = __set_bundle(b, AUL_SVC_K_PKG_NAME, alias_id); + free(alias_id); + } + + return ret; +} + +SLPAPI int aul_svc_set_category(bundle *b, const char *category) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_category is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_CATEGORY, category); +} + +SLPAPI int aul_svc_set_launch_mode(bundle *b, const char *mode) +{ + if (b == NULL) { + _E("bundle for aul_svc_set_launch_mode is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_LAUNCH_MODE, mode); +} + +SLPAPI int aul_svc_run_service(bundle *b, int request_code, + aul_svc_res_fn cbfunc, + void *data) +{ + return aul_svc_run_service_with_uid(b, request_code, cbfunc, data, getuid()); +} + +SLPAPI int aul_svc_run_service_with_uid(bundle *b, int request_code, + aul_svc_res_fn cbfunc, + void *data, uid_t uid) +{ + aul_svc_resolve_info_t info; + char *pkgname; + char *operation; + int pkg_count = 0; + int ret = -1; + + GSList *pkg_list = NULL; + GSList *iter = NULL; + char *list_item; + + if (b == NULL) { + _E("bundle for aul_svc_set_appid is NULL"); + return AUL_SVC_RET_EINVAL; + } + + pkgname = (char *)aul_svc_get_pkgname(b); + operation = (char *)aul_svc_get_operation(b); + + /* explict*/ + if (pkgname) { + if (operation == NULL) + aul_svc_set_operation(b, AUL_SVC_OPERATION_DEFAULT); + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + return ret; + } + + /* share panel */ + if (operation && (strcmp(operation, AUL_SVC_OPERATION_SHARE) == 0 + || strcmp(operation, AUL_SVC_OPERATION_MULTI_SHARE) == 0 + || strcmp(operation, AUL_SVC_OPERATION_SHARE_TEXT) == 0)) { + ret = __run_svc_with_pkgname(SHARE_PANEL, b, request_code, cbfunc, data); + return ret; + } + + memset(&info, 0, sizeof(aul_svc_resolve_info_t)); + ret = __get_resolve_info(b, &info); + if (ret < 0) { + __free_resolve_info_data(&info); + return ret; + } + + SECURE_LOGD("op - %s / mime - %s / scheme - %s\n", info.op, info.origin_mime, + info.scheme); + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + ret = AUL_SVC_RET_EILLACC; + goto end; + } + + /*uri*/ + pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri, uid); + if (pkgname == NULL) { + __get_list_with_condition_mime_extened_with_collation(info.op, info.uri, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + pkg_count = g_slist_length(pkg_list); + if (pkg_count > 0) { + + if (info.uri_r_info) { + __get_list_with_condition_mime_extened(info.op, info.uri_r_info, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + __get_list_with_condition_mime_extened(info.op, info.scheme, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + __get_list_with_condition_mime_extened(info.op, "*", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + if (info.scheme && (strcmp(info.scheme, "file") == 0) + && info.mime && (strcmp(info.mime, "NULL") != 0)) { + __get_list_with_condition_mime_extened(info.op, "NULL", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + if (info.category) { + __get_list_with_category(info.category, &pkg_list, uid); + } + + __get_list_with_submode(info.op, info.win_id, &pkg_list, uid); + + pkg_count = g_slist_length(pkg_list); + _D("pkg_count : %d", pkg_count); + + if (pkg_count == 1) { + pkgname = (char *)pkg_list->data; + if (pkgname != NULL) { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + goto end; + } + } else { + bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri); + ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code, cbfunc, data); + goto end; + } + for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) { + list_item = (char *)iter->data; + g_free(list_item); + } + g_slist_free(pkg_list); + pkg_list = NULL; + } + } else { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + free(pkgname); + goto end; + } + + /*scheme & host*/ + if (info.uri_r_info) { + pkgname = _svc_db_get_app(info.op, info.origin_mime, info.uri_r_info, uid); + + if (pkgname == NULL) { + __get_list_with_condition_mime_extened(info.op, info.uri_r_info, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + pkg_count = g_slist_length(pkg_list); + if (pkg_count > 0) { + __get_list_with_condition_mime_extened(info.op, info.scheme, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + __get_list_with_condition_mime_extened(info.op, "*", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + if (info.scheme && (strcmp(info.scheme, "file") == 0) + && info.mime && (strcmp(info.mime, "NULL") != 0)) { + __get_list_with_condition_mime_extened(info.op, "NULL", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + if (info.category) { + __get_list_with_category(info.category, &pkg_list, uid); + } + + __get_list_with_submode(info.op, info.win_id, &pkg_list, uid); + + pkg_count = g_slist_length(pkg_list); + _D("pkg_count : %d", pkg_count); + + if (pkg_count == 1) { + pkgname = (char *)pkg_list->data; + if (pkgname != NULL) { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + goto end; + } + } else { + bundle_add(b, AUL_SVC_K_URI_R_INFO, info.uri_r_info); + ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code, cbfunc, data); + goto end; + } + } + for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) { + list_item = (char *)iter->data; + g_free(list_item); + } + g_slist_free(pkg_list); + pkg_list = NULL; + } else { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + free(pkgname); + goto end; + } + } + + /*scheme*/ + pkgname = _svc_db_get_app(info.op, info.origin_mime, info.scheme, uid); + + if (pkgname == NULL) { + __get_list_with_condition_mime_extened(info.op, info.scheme, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + __get_list_with_condition_mime_extened(info.op, "*", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + if (info.scheme && (strcmp(info.scheme, "file") == 0) + && info.mime && (strcmp(info.mime, "NULL") != 0)) { + __get_list_with_condition_mime_extened(info.op, "NULL", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + if (info.category) { + __get_list_with_category(info.category, &pkg_list, uid); + } + + __get_list_with_submode(info.op, info.win_id, &pkg_list, uid); + + pkg_count = g_slist_length(pkg_list); + _D("pkg_count : %d", pkg_count); + + if (pkg_count == 1) { + pkgname = (char *)pkg_list->data; + if (pkgname != NULL) { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + } + } else if (pkg_count < 1) { + __free_resolve_info_data(&info); + return AUL_SVC_RET_ENOMATCH; + } else { + bundle_add(b, AUL_SVC_K_URI_R_INFO, info.scheme); + ret = __run_svc_with_pkgname(APP_SELECTOR, b, request_code, cbfunc, data); + } + + for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) { + list_item = (char *)iter->data; + g_free(list_item); + } + g_slist_free(pkg_list); + } else { + ret = __run_svc_with_pkgname(pkgname, b, request_code, cbfunc, data); + free(pkgname); + } + +end: + __free_resolve_info_data(&info); + + return ret; +} + +SLPAPI int aul_svc_get_list(bundle *b, aul_svc_info_iter_fn iter_fn, + void *data) +{ + return aul_svc_get_list_with_uid(b, iter_fn, data, getuid()); +} + +SLPAPI int aul_svc_get_list_with_uid(bundle *b, aul_svc_info_iter_fn iter_fn, + void *data, uid_t uid) +{ + aul_svc_resolve_info_t info; + char *pkgname = NULL; + int pkg_count; + int ret = -1; + + GSList *pkg_list = NULL; + GSList *iter = NULL; + + if (b == NULL) { + _E("bundle for aul_svc_run_service is NULL"); + return AUL_SVC_RET_EINVAL; + } + + if (iter_fn == NULL) { + _E("iter_fn for aul_svc_run_service is NULL"); + return AUL_SVC_RET_EINVAL; + } + + + /* parse bundle */ + memset(&info, 0, sizeof(aul_svc_resolve_info_t)); + ret = __get_resolve_info(b, &info); + if (ret < 0) { + __free_resolve_info_data(&info); + return ret; + } + + _D("operation - %s / shceme - %s / mime - %s\n", info.op, info.scheme, + info.mime); + + __get_list_with_condition_mime_extened_with_collation(info.op, info.uri, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + if (info.uri_r_info) { + __get_list_with_condition_mime_extened(info.op, info.uri_r_info, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + __get_list_with_condition_mime_extened(info.op, info.scheme, + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + __get_list_with_condition_mime_extened(info.op, "*", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + + if (info.scheme && (strcmp(info.scheme, "file") == 0) + && info.mime && (strcmp(info.mime, "NULL") != 0)) { + __get_list_with_condition_mime_extened(info.op, "NULL", + info.mime, info.m_type, info.s_type, &pkg_list, uid); + } + + if (info.category) { + __get_list_with_category(info.category, &pkg_list, uid); + } + + __get_list_with_submode(info.op, info.win_id, &pkg_list, uid); + + pkg_count = g_slist_length(pkg_list); + if (pkg_count == 0) { + _E("Cannot find associated application"); + + __free_resolve_info_data(&info); + return AUL_SVC_RET_ENOMATCH; + } + + for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) { + pkgname = iter->data; + SECURE_LOGD("PKGNAME : %s\n", pkgname); + if ( iter_fn(pkgname, data) != 0) + break; + g_free(pkgname); + } + + g_slist_free(pkg_list); + __free_resolve_info_data(&info); + + return AUL_SVC_RET_OK; +} + +SLPAPI int aul_svc_get_all_defapps(aul_svc_info_iter_fn iter_fn, void *data) +{ + return aul_svc_get_all_defapps_with_uid(iter_fn, data, getuid()); +} + +SLPAPI int aul_svc_get_all_defapps_with_uid(aul_svc_info_iter_fn iter_fn, + void *data, uid_t uid) +{ + char *pkgname = NULL; + int ret = -1; + + GSList *pkg_list = NULL; + GSList *iter = NULL; + + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + return AUL_SVC_RET_EILLACC; + } + + ret = _svc_db_get_list_with_all_defapps(&pkg_list, uid); + if (ret < 0) + return ret; + + for (iter = pkg_list; iter != NULL; iter = g_slist_next(iter)) { + pkgname = iter->data; + if ( iter_fn(pkgname, data) != 0) + break; + g_free(pkgname); + } + + g_slist_free(pkg_list); + + return AUL_SVC_RET_OK; +} + +SLPAPI const char *aul_svc_get_operation(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_OPERATION); +} + +SLPAPI const char *aul_svc_get_uri(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_URI); +} + +SLPAPI const char *aul_svc_get_mime(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_MIME); +} + +SLPAPI const char *aul_svc_get_data(bundle *b, const char *key) +{ + return bundle_get_val(b, key); +} + +SLPAPI const char **aul_svc_get_data_array(bundle *b, const char *key, int *len) +{ + return bundle_get_str_array(b, key, len); +} + +SLPAPI const char *aul_svc_get_pkgname(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_PKG_NAME); +} + +SLPAPI const char *aul_svc_get_appid(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_PKG_NAME); +} + +SLPAPI const char *aul_svc_get_category(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_CATEGORY); +} + +SLPAPI const char *aul_svc_get_launch_mode(bundle *b) +{ + return bundle_get_val(b, AUL_SVC_K_LAUNCH_MODE); +} + +SLPAPI int aul_svc_create_result_bundle(bundle *inb, bundle **outb) +{ + int ret = -1; + + if (inb == NULL || outb == NULL) { + _E("bundle is NULL"); + return AUL_SVC_RET_EINVAL; + } + + ret = aul_create_result_bundle(inb, outb); + + /* add additional bundle */ + /* bundle_add(outb, " ", " "); */ + + if (ret == AUL_R_OK) + ret = AUL_SVC_RET_OK; + else if (ret == AUL_R_EINVAL) + ret = AUL_SVC_RET_EINVAL; + else + ret = AUL_SVC_RET_ERROR; + + return ret; +} + +SLPAPI int aul_svc_send_result(bundle *b, aul_svc_result_val result) +{ + int ret; + char tmp[MAX_LOCAL_BUFSZ]; + + if (b == NULL) { + _E("aul_svc_send_result is NULL"); + return AUL_SVC_RET_EINVAL; + } + + if (result != AUL_SVC_RES_OK && result != AUL_SVC_RES_NOT_OK) { + _E("invalid result %d", (int)result); + return AUL_SVC_RET_EINVAL; + } + + /* add result_code to bundle */ + snprintf(tmp, MAX_LOCAL_BUFSZ, "%d", (int)result); + ret = __set_bundle(b, AUL_SVC_K_RES_VAL, tmp); + if (ret < 0) + return AUL_SVC_RET_ERROR; + + ret = aul_send_service_result(b); + + /* remove result_code from bundle */ + bundle_del(b, AUL_SVC_K_RES_VAL); + + return ret; +} + +SLPAPI int aul_svc_set_defapp(const char *op, const char *mime_type, + const char *uri, + const char *defapp) +{ + return aul_svc_set_defapp_with_uid(op, mime_type, uri, defapp, getuid()); +} + +SLPAPI int aul_svc_set_defapp_with_uid(const char *op, const char *mime_type, + const char *uri, + const char *defapp, + uid_t uid) +{ + int ret; + + if (op == NULL || defapp == NULL) + return AUL_SVC_RET_EINVAL; + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + return AUL_SVC_RET_EILLACC; + } + + ret = _svc_db_add_app(op, mime_type, uri, defapp, uid); + + if (ret < 0) + return AUL_SVC_RET_ERROR; + + return AUL_SVC_RET_OK; +} + +SLPAPI int aul_svc_unset_defapp(const char *defapp) +{ + return aul_svc_unset_defapp_with_uid(defapp, getuid()); +} + +SLPAPI int aul_svc_unset_defapp_with_uid(const char *defapp, uid_t uid) +{ + int ret; + + if (defapp == NULL) + return AUL_SVC_RET_EINVAL; + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + return AUL_SVC_RET_EILLACC; + } + + ret = _svc_db_delete_with_pkgname(defapp, uid); + + if (ret < 0) + return AUL_SVC_RET_ERROR; + + return AUL_SVC_RET_OK; +} + +SLPAPI int aul_svc_unset_all_defapps() +{ + return aul_svc_unset_all_defapps_with_uid(getuid()); +} + +SLPAPI int aul_svc_unset_all_defapps_with_uid(uid_t uid) +{ + int ret; + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + return AUL_SVC_RET_EILLACC; + } + + ret = _svc_db_delete_all(uid); + + if (ret < 0) + return AUL_SVC_RET_ERROR; + + return AUL_SVC_RET_OK; +} + +SLPAPI int aul_svc_is_defapp(const char *pkg_name) +{ + return aul_svc_is_defapp_with_uid(pkg_name, getuid()); +} + +SLPAPI int aul_svc_is_defapp_with_uid(const char *pkg_name, uid_t uid) +{ + int ret; + + ret = _svc_db_check_perm(uid); + if (ret < 0) { + _E("permission error : %d", ret); + return AUL_SVC_RET_EILLACC; + } + + return _svc_db_is_defapp(pkg_name, uid); +} + +SLPAPI int aul_svc_data_is_array(bundle *b, const char *key) +{ + int type; + type = bundle_get_type(b, key); + + if (type <= 0) + return 0; + + if (type & BUNDLE_TYPE_ARRAY) + return 1; + return 0; +} + +SLPAPI int aul_svc_allow_transient_app(bundle *b, int wid) +{ + char win_id[MAX_LOCAL_BUFSZ]; + + snprintf(win_id, MAX_LOCAL_BUFSZ, "%d", wid); + + if (b == NULL) { + _E("bundle for aul_svc_allow_transient_app is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, AUL_SVC_K_WIN_ID, win_id); +} + +SLPAPI int aul_svc_request_transient_app(bundle *b, int callee_wid, + aul_svc_host_res_fn cbfunc, void *data) +{ + return 0; +} + +SLPAPI int aul_svc_subapp_terminate_request_pid(int pid) +{ + int cpid = getpid(); + int lcnt; + int *lpids = NULL; + int i; + + aul_app_group_get_leader_pids(&lcnt, &lpids); + for (i = 0; i < lcnt; i++) { + if (lpids[i] == cpid) { + int cnt; + int *pids = NULL; + + aul_app_group_get_group_pids(cpid, &cnt, &pids); + + if (cnt == 0) { + free(lpids); + if (pids) + free(pids); + + return aul_subapp_terminate_request_pid(pid); + } + + if (pids != NULL) + free(pids); + break; + } + } + + if (lpids != NULL) + free(lpids); + + return aul_app_group_clear_top(); +} + SLPAPI int aul_send_service_result(bundle *b) { return aul_send_result(b, 0); } +SLPAPI int aul_svc_subscribe_launch_result(bundle *b, const char *result) +{ + if (b == NULL) { + _E("bundle for aul_svc_subscribe_launch_result is NULL"); + return AUL_SVC_RET_EINVAL; + } + + return __set_bundle(b, result, "1"); +} diff --git a/src/service_db.c b/src/service_db.c new file mode 100755 index 00000000..f5d64e25 --- /dev/null +++ b/src/service_db.c @@ -0,0 +1,769 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <glib.h> +#include <unistd.h> +#include <ctype.h> +#include <tzplatform_config.h> + +#include "aul_svc_db.h" +#include "simple_util.h" + +#define APP_INFO_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db") + +#define QUERY_MAX_LEN 8192 +#define URI_MAX_LEN 4096 +#define BUF_MAX_LEN 1024 +#define ROOT_UID 0 + +#define SVC_COLLATION "appsvc_collation" + +#define QUERY_ATTACH "attach database '%s' as Global" +#define QUERY_CREATE_VIEW_1 "CREATE temp VIEW package_app_app_control as select * "\ + "from (select *,0 as for_all_users from main.package_app_app_control union select *,1 as for_all_users from Global.package_app_app_control)" +#define QUERY_CREATE_VIEW_2 "CREATE temp VIEW package_app_info as select * "\ + "from (select *,0 as for_all_users from main.package_app_info union select *,1 as for_all_users from Global.package_app_info)" +#define QUERY_CREATE_TABLE_APPSVC "create table if not exists appsvc " \ + "(operation text, " \ + "mime_type text, " \ + "uri text, " \ + "pkg_name text, " \ + "PRIMARY KEY(pkg_name)) " + +static sqlite3 *svc_db = NULL; +static sqlite3 *app_info_db = NULL; + +static int __attach_create_view_appinfo_db(sqlite3 *handle, uid_t uid) +{ + char *error_message = NULL; + char query_attach[QUERY_MAX_LEN] = {'\0'}; + if (uid != GLOBAL_USER) { + snprintf(query_attach, QUERY_MAX_LEN - 1, QUERY_ATTACH, APP_INFO_DB_PATH); + if (SQLITE_OK != + sqlite3_exec(handle, query_attach, + NULL, NULL, &error_message)) { + _D("Don't execute query = %s error message = %s\n", + query_attach, error_message); + sqlite3_free(error_message); + } + if (SQLITE_OK != + sqlite3_exec(handle, QUERY_CREATE_VIEW_1, + NULL, NULL, &error_message)) { + _D("Don't execute query = %s error message = %s\n", + QUERY_CREATE_VIEW_1, error_message); + sqlite3_free(error_message); + } + if (SQLITE_OK != + sqlite3_exec(handle, QUERY_CREATE_VIEW_2, + NULL, NULL, &error_message)) { + _D("Don't execute query = %s error message = %s\n", + QUERY_CREATE_VIEW_2, error_message); + sqlite3_free(error_message); + } + } + return SQLITE_OK; +} + +static int __mkdir(const char *dir, mode_t mode) +{ + char tmp[PATH_MAX]; + char *p = NULL; + size_t len; + int ret; + + snprintf(tmp, sizeof(tmp), "%s", dir); + len = strlen(tmp); + if(tmp[len - 1] == '/') + tmp[len - 1] = 0; + for(p = tmp + 1; *p; p++) { + if(*p == '/') { + *p = 0; + ret = mkdir(tmp, mode); + if (ret && errno != EEXIST) + return ret; + *p = '/'; + } + } + return mkdir(tmp, mode); +} + +static void __mkdir_for_user(const char* dir, uid_t uid, gid_t gid) { + int ret = 0; + + ret = __mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH); + if (ret == -1 && errno != EEXIST) { + _E("Fail to create directory %s %d", dir, errno); + } else if (getuid() == ROOT_UID) { + ret = chown(dir, uid, gid); + if (ret == -1) + _E("Fail to chown %s %d.%d, because %s", dir, uid, gid, strerror(errno)); + } +} + +static char *__get_svc_db(uid_t uid) +{ + const char *appsvc_db = NULL; + const char *db_path = NULL; + uid_t uid_caller = getuid(); + gid_t gid = ROOT_UID; + + if (uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) && uid != ROOT_UID) { + tzplatform_set_user(uid); + appsvc_db = tzplatform_mkpath(TZ_USER_DB, ".appsvc.db"); + db_path = tzplatform_getenv(TZ_USER_DB); + gid = tzplatform_getgid(TZ_USER_NAME); + tzplatform_reset_user(); + } else { + _E("Fail to get appsvc db. only regular user has appsvc db"); + return NULL; + } + + if (uid_caller == ROOT_UID || uid_caller == uid) + __mkdir_for_user (db_path, uid, gid); + + return appsvc_db; +} + + +static char *__get_app_info_db(uid_t uid) +{ + const char *app_info_db = NULL; + const char *db_path = NULL; + uid_t uid_caller = getuid(); + gid_t gid = ROOT_UID; + + if (uid == ROOT_UID) { + _E("Fail to get appsvc db. root is not allowed"); + return NULL; + } + + if (uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) { + tzplatform_set_user(uid); + app_info_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db"); + db_path = tzplatform_getenv(TZ_USER_DB); + gid = tzplatform_getgid(TZ_USER_NAME); + tzplatform_reset_user(); + } else { + app_info_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db"); + db_path = tzplatform_getenv(TZ_SYS_DB); + } + + if (uid_caller == ROOT_UID || uid_caller == uid) + __mkdir_for_user (db_path, uid, gid); + + return app_info_db; +} + +/** + * db initialize + */ + +static int __init(uid_t uid) +{ + int rc; + + if (svc_db) { + _D("Already initialized\n"); + return 0; + } + + rc = sqlite3_open(__get_svc_db(uid), &svc_db); + if (rc) { + _E("Can't open database: %d, %s, extended: %d", rc, sqlite3_errmsg(svc_db), + sqlite3_extended_errcode(svc_db)); + goto err; + } + + rc = sqlite3_exec(svc_db, "PRAGMA journal_mode = PERSIST", NULL, NULL, NULL); + if (SQLITE_OK != rc) { + _E("Fail to change journal mode\n"); + goto err; + } + rc = sqlite3_exec(svc_db, QUERY_CREATE_TABLE_APPSVC, NULL, NULL, NULL); + if(SQLITE_OK!=rc){ + _E("Fail to create tables\n"); + goto err; + } + + return 0; +err: + sqlite3_close(svc_db); + svc_db = NULL; + return -1; +} + +static int __collate_appsvc(void *ucol, int str1_len, const void *str1, + int str2_len, const void *str2) +{ + char *saveptr1 = NULL; + char *saveptr2 = NULL; + char *dup_str1; + char *dup_str2; + char *token; + char *in_op; + char *in_uri; + char *in_mime; + char *op; + char *uri; + char *mime; + + if (str1 == NULL || str2 == NULL) + return -1; + + dup_str1 = strdup(str1); + dup_str2 = strdup(str2); + + in_op = strtok_r(dup_str2, "|", &saveptr1); + in_uri = strtok_r(NULL, "|", &saveptr1); + in_mime = strtok_r(NULL, "|", &saveptr1); + + if (!(in_op && in_uri && in_mime)) { + _D("op(%s) uri(%s) mime(%s)", in_op, in_uri, in_mime); + free(dup_str1); + free(dup_str2); + return -1; + } + + token = strtok_r(dup_str1, ";", &saveptr1); + + if (token == NULL) { + free(dup_str1); + free(dup_str2); + return -1; + } + + do { + op = strtok_r(token, "|", &saveptr2); + uri = strtok_r(NULL, "|", &saveptr2); + mime = strtok_r(NULL, "|", &saveptr2); + + if (!(op && uri && mime)) { + _D("op(%s) uri(%s) mime(%s)", op, uri, mime); + continue; + } + + if ( (strcmp(op, in_op) == 0) && (strcmp(mime, in_mime) == 0) ) { + SECURE_LOGD("%s %s %s %s %s %s", op, in_op, mime, in_mime, uri, in_uri); + if (g_pattern_match_simple(uri, in_uri)) { + SECURE_LOGD("in_uri : %s | uri : %s", in_uri, uri); + free(dup_str1); + free(dup_str2); + return 0; + } + } + } while ( (token = strtok_r(NULL, ";", &saveptr1)) ); + + free(dup_str1); + free(dup_str2); + + return -1; +} + +static int __init_app_info_db(uid_t uid) +{ + int rc; + + if (app_info_db) { + _D("Already initialized\n"); + return 0; + } + + rc = sqlite3_open_v2(__get_app_info_db(uid), &app_info_db, SQLITE_OPEN_READONLY, NULL); + if (rc) { + _E("Can't open database: %d, %s, extended: %d", rc, sqlite3_errmsg(app_info_db), + sqlite3_extended_errcode(app_info_db)); + goto err; + } + + rc = __attach_create_view_appinfo_db(app_info_db, uid); + if (SQLITE_OK != rc) { + _D("Fail to change journal mode\n"); + goto err; + } + + rc = sqlite3_exec(app_info_db, "PRAGMA journal_mode = PERSIST", NULL, NULL, + NULL); + if (SQLITE_OK != rc) { + _D("Fail to change journal mode\n"); + goto err; + } + + sqlite3_create_collation(app_info_db, SVC_COLLATION, SQLITE_UTF8, NULL, + __collate_appsvc); + + return 0; +err: + sqlite3_close(app_info_db); + app_info_db = NULL; + return -1; +} + + +static int __fini(void) +{ + if (svc_db) { + sqlite3_close(svc_db); + svc_db = NULL; + } + return 0; +} + +int _svc_db_check_perm(uid_t uid) +{ + int ret = 0; + if (__init(uid) < 0) + return -1; + + ret = access(__get_svc_db(uid), R_OK | W_OK); + return ret; +} + +int _svc_db_add_app(const char *op, const char *mime_type, const char *uri, + const char *pkg_name, uid_t uid) +{ + char m[BUF_MAX_LEN]; + char u[URI_MAX_LEN]; + const char insert_query[] = + "insert into appsvc( operation, mime_type, uri, pkg_name) values(?,?,?,?)"; + sqlite3_stmt* p_statement; + int result; + + if (__init(uid) < 0) + return -1; + + if (op == NULL ) + return -1; + + if (mime_type == NULL) + strncpy(m, "NULL", BUF_MAX_LEN - 1); + else + strncpy(m, mime_type, BUF_MAX_LEN - 1); + + if (uri == NULL) + strncpy(u, "NULL", URI_MAX_LEN - 1); + else + strncpy(u, uri, URI_MAX_LEN - 1); + + + result = sqlite3_prepare_v2(svc_db, insert_query, strlen(insert_query), + &p_statement, NULL); + if (result != SQLITE_OK) { + _E("Sqlite3 error [%d] : <%s> preparing <%s> querry\n", result, + sqlite3_errmsg(svc_db), insert_query); + return -1; + } + + sqlite3_bind_text(p_statement, 1, op, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(p_statement, 2, m, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(p_statement, 3, u, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(p_statement, 4, pkg_name, -1, SQLITE_TRANSIENT); + + + result = sqlite3_step(p_statement); + if (result != SQLITE_DONE) { + _E("Sqlite3 error [%d] : <%s> executing statement\n", result, + sqlite3_errmsg(svc_db)); + } + + result = sqlite3_finalize(p_statement); + if (result != SQLITE_OK) { + _E("Sqlite3 error [%d] : <%s> finalizing statement\n", result, + sqlite3_errmsg(svc_db)); + } + + __fini(); + return 0; +} + +int _svc_db_delete_with_pkgname(const char *pkg_name, uid_t uid) +{ + const char delete_query[] = "delete from appsvc where pkg_name = ?;"; + sqlite3_stmt* p_statement; + int result; + + if (pkg_name == NULL) { + _E("Invalid argument: data to delete is NULL\n"); + return -1; + } + + if (__init(uid) < 0) + return -1; + + result = sqlite3_prepare_v2(svc_db, delete_query, strlen(delete_query), + &p_statement, NULL); + if (result != SQLITE_OK) { + _E("Sqlite3 error [%d] : <%s> preparing <%s> querry\n", result, + sqlite3_errmsg(svc_db), delete_query); + return -1; + } + + sqlite3_bind_text(p_statement, 1, pkg_name, -1, SQLITE_TRANSIENT); + + result = sqlite3_step(p_statement); + if (result != SQLITE_DONE) { + _E("Sqlite3 error [%d] : <%s> executing statement\n", result, + sqlite3_errmsg(svc_db)); + } + + result = sqlite3_finalize(p_statement); + if (result != SQLITE_OK) { + _E("Sqlite3 error [%d] : <%s> finalizing statement\n", result, + sqlite3_errmsg(svc_db)); + } + + __fini(); + + return 0; +} + +int _svc_db_delete_all(uid_t uid) +{ + char query[QUERY_MAX_LEN]; + char* error_message = NULL; + + if (__init(uid) < 0) + return -1; + + snprintf(query, QUERY_MAX_LEN, "delete from appsvc;"); + + if (SQLITE_OK != sqlite3_exec(svc_db, query, NULL, NULL, &error_message)) { + _E("Don't execute query = %s, error message = %s\n", query, error_message); + return -1; + } + + __fini(); + + return 0; +} + +int _svc_db_is_defapp(const char *pkg_name, uid_t uid) +{ + char query[QUERY_MAX_LEN]; + sqlite3_stmt *stmt; + int cnt = 0; + int ret = -1; + + if (pkg_name == NULL) { + _E("Invalid argument: data to delete is NULL\n"); + return 0; + } + + if (__init(uid) < 0) + return 0; + + snprintf(query, QUERY_MAX_LEN, + "select count(*) from appsvc where pkg_name = '%s';", pkg_name); + + ret = sqlite3_prepare(svc_db, query, sizeof(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(svc_db)); + return -1; + } + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + cnt = sqlite3_column_int(stmt, 0); + } + sqlite3_finalize(stmt); + + __fini(); + + if (cnt < 1) return 0; + + return 1; +} + +char* _svc_db_get_app(const char *op, const char *mime_type, const char *uri, + uid_t uid) +{ + char m[BUF_MAX_LEN]; + char u[URI_MAX_LEN]; + char query[QUERY_MAX_LEN]; + sqlite3_stmt* stmt; + int ret; + char* pkgname; + char* ret_val = NULL; + + if (op == NULL ) + return NULL; + + if (mime_type == NULL) + strncpy(m, "NULL", BUF_MAX_LEN - 1); + else + strncpy(m, mime_type, BUF_MAX_LEN - 1); + + if (uri == NULL) + strncpy(u, "NULL", URI_MAX_LEN - 1); + else + strncpy(u, uri, URI_MAX_LEN - 1); + + if (__init(uid) < 0) + return NULL; + + + snprintf(query, QUERY_MAX_LEN, + "select pkg_name from appsvc where operation='%s' and mime_type='%s' and uri='%s'", + \ + op, m, u); + + SECURE_LOGD("query : %s\n", query); + + ret = sqlite3_prepare(svc_db, query, strlen(query), &stmt, NULL); + if ( ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(svc_db)); + goto db_fini; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + _D("no result"); + goto stmt_finialize; + } + + pkgname = (char*) sqlite3_column_text(stmt, 0); + if (pkgname) { + ret_val = malloc(BUF_MAX_LEN); + if (ret_val == NULL) { + _E("out of memory"); + goto stmt_finialize; + } + + strncpy(ret_val, (const char *)sqlite3_column_text(stmt, 0), BUF_MAX_LEN - 1); + } + + SECURE_LOGD("pkgname : %s\n", pkgname); + +stmt_finialize : + ret = sqlite3_finalize(stmt); + if ( ret != SQLITE_OK) { + _D("finalize error(%d)", ret); + } + +db_fini : + __fini(); + + return ret_val; +} + +static int __appid_compare(gconstpointer data1, gconstpointer data2) +{ + char *a = (char *)data1; + char *b = (char *)data2; + return strcmp(a, b); +} + +int _svc_db_adjust_list_with_submode(int mainapp_mode, char *win_id, GSList **pkg_list, uid_t uid) +{ + sqlite3_stmt* stmt; + int ret; + char query[QUERY_MAX_LEN]; + char *subappid = NULL; + char *submode_mainid = NULL; + char *excluded_appid = NULL; + GSList *subapp = NULL; + GSList *mainapp = NULL; + + if (__init_app_info_db(uid) < 0) + return 0; + + snprintf(query, QUERY_MAX_LEN, "select ac.app_id, ai.app_submode_mainid from package_app_app_control as ac, package_app_info ai where ac.app_id = ai.app_id and ai.app_submode_mainid!=''"); + ret = sqlite3_prepare(app_info_db, query, sizeof(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(app_info_db)); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + subappid = (char *)sqlite3_column_text(stmt, 0); + submode_mainid = (char *)sqlite3_column_text(stmt, 1); + subapp = g_slist_find_custom(*pkg_list, subappid, __appid_compare); + + if (subapp == NULL) + continue; + + // find if the main app is in the pkg_list + mainapp = g_slist_find_custom(*pkg_list, submode_mainid, __appid_compare); + if (mainapp == NULL) + continue; + + if (win_id && !mainapp_mode) + //subapp mode - remove mainapp from list + excluded_appid = (char *)mainapp->data; + else + //mainapp mode - remove subapp from list + excluded_appid = (char *)subapp->data; + + if (excluded_appid) { + _E("remove %s from app list with submode", excluded_appid); + *pkg_list = g_slist_remove(*pkg_list, excluded_appid); + free(excluded_appid); + excluded_appid = NULL; + } + } + + ret = sqlite3_finalize(stmt); + return 0; +} + +int _svc_db_get_list_with_condition(char *op, char *uri, char *mime, + GSList **pkg_list, uid_t uid) +{ + char query[QUERY_MAX_LEN]; + sqlite3_stmt* stmt; + int ret; + GSList *iter = NULL; + char *str = NULL; + char *pkgname = NULL; + int found; + + if (__init_app_info_db(uid) < 0) + return 0; + + snprintf(query, QUERY_MAX_LEN, + "select ac.app_id from package_app_app_control as ac, package_app_info ai where ac.app_id = ai.app_id and ac.app_control like '%%%s|%s|%s%%' and ai.component_type='uiapp'", + op, uri, mime); + SECURE_LOGD("query : %s\n", query); + + ret = sqlite3_prepare(app_info_db, query, strlen(query), &stmt, NULL); + if ( ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(app_info_db)); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + str = (char *)sqlite3_column_text(stmt, 0); + found = 0; + for (iter = *pkg_list; iter != NULL; iter = g_slist_next(iter)) { + pkgname = (char *)iter->data; + if (strncmp(str, pkgname, MAX_PACKAGE_STR_SIZE - 1) == 0) { + found = 1; + break; + } + } + if (found == 0) { + pkgname = strdup(str); + *pkg_list = g_slist_append(*pkg_list, (void *)pkgname); + _D("%s is added", pkgname); + } + } + + ret = sqlite3_finalize(stmt); + + return 0; +} + +int _svc_db_get_list_with_collation(char *op, char *uri, char *mime, + GSList **pkg_list, uid_t uid) +{ + char query[QUERY_MAX_LEN]; + sqlite3_stmt* stmt; + int ret; + GSList *iter = NULL; + char *str = NULL; + char *pkgname = NULL; + int found; + + if (__init_app_info_db(uid) < 0) { + return 0; + } + + snprintf(query, QUERY_MAX_LEN, + "select ac.app_id from package_app_app_control as ac, package_app_info ai where ac.app_id = ai.app_id and ac.app_control='%s|%s|%s' collate appsvc_collation and ai.component_type='uiapp'", + op, uri, mime); + SECURE_LOGD("query : %s\n", query); + + ret = sqlite3_prepare(app_info_db, query, strlen(query), &stmt, NULL); + if ( ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(app_info_db)); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + str = (char *)sqlite3_column_text(stmt, 0); + found = 0; + for (iter = *pkg_list; iter != NULL; iter = g_slist_next(iter)) { + pkgname = (char *)iter->data; + if (strncmp(str, pkgname, MAX_PACKAGE_STR_SIZE - 1) == 0) { + found = 1; + break; + } + } + if (found == 0) { + pkgname = strdup(str); + *pkg_list = g_slist_append(*pkg_list, (void *)pkgname); + _D("%s is added", pkgname); + } + } + + ret = sqlite3_finalize(stmt); + + return 0; +} + +int _svc_db_get_list_with_all_defapps(GSList **pkg_list, uid_t uid) +{ + char query[QUERY_MAX_LEN]; + sqlite3_stmt* stmt; + int ret; + GSList *iter = NULL; + char *str = NULL; + char *pkgname = NULL; + int found; + + if (__init(uid) < 0) + return -1; + + snprintf(query, QUERY_MAX_LEN, "select pkg_name from appsvc"); + + ret = sqlite3_prepare(svc_db, query, sizeof(query), &stmt, NULL); + if ( ret != SQLITE_OK) { + _E("prepare error, ret = %d, extended = %d\n", ret, + sqlite3_extended_errcode(svc_db)); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + str = (char *)sqlite3_column_text(stmt, 0); + found = 0; + for (iter = *pkg_list; iter != NULL; iter = g_slist_next(iter)) { + pkgname = (char *)iter->data; + if (strncmp(str, pkgname, MAX_PACKAGE_STR_SIZE - 1) == 0) { + found = 1; + break; + } + } + if (found == 0) { + pkgname = strdup(str); + *pkg_list = g_slist_append(*pkg_list, (void *)pkgname); + _D("[%s] is def app", pkgname); + } + } + + ret = sqlite3_finalize(stmt); + + return 0; +} + |