From b0dd9c11be43272070381ddb3bda44fb5faeb72a Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Tue, 8 Sep 2015 22:08:01 +0900 Subject: [PATCH] tizen 2.3.1 release --- AUTHORS | 0 CMakeLists.txt | 19 +- LICENSE | 0 TC/_export_env.sh | 8 + TC/_export_target_env.sh | 7 + TC/build.sh | 16 + TC/clean.sh | 11 + TC/config | 2 + TC/execute.sh | 15 + TC/testcase/Makefile | 24 + TC/testcase/tslist | 7 + TC/testcase/utc_alarm.c | 766 +++++ TC/testcase/utc_app.c | 450 +++ TC/testcase/utc_i18n.c | 77 + TC/testcase/utc_preference.c | 544 ++++ TC/testcase/utc_service.c | 2948 ++++++++++++++++++++ TC/tet_scen | 7 + TC/tetbuild.cfg | 5 + TC/tetclean.cfg | 5 + TC/tetexec.cfg | 5 + alarm/CMakeLists.txt | 65 + {src => alarm}/alarm.c | 184 +- app_common/CMakeLists.txt | 69 + {src => app_common}/app_error.c | 15 +- app_common/app_event.c | 155 + {src => app_common}/app_finalizer.c | 22 +- {src => app_common}/app_package.c | 42 +- app_common/app_path.c | 72 + app_control/CMakeLists.txt | 65 + app_control/app_control.c | 1397 ++++++++++ capi-appfw-application.manifest | 5 + ...fw-application.pc.in => capi-appfw-module.pc.in | 2 +- debian/control | 2 +- doc/appfw_alarm_doc.h | 61 + doc/appfw_app_common_doc.h | 84 + doc/appfw_app_control_doc.h | 33 + doc/appfw_app_doc.h | 315 +++ doc/appfw_i18n_doc.h | 45 + doc/appfw_preference_doc.h | 44 + doc/images/capi_appfw_application_lifecycle.png | Bin 0 -> 30482 bytes doc/images/capi_appfw_application_package.png | Bin 0 -> 8295 bytes doc/images/capi_appfw_application_states.png | Bin 0 -> 32111 bytes include/app.h | 469 ++-- include/app_alarm.h | 278 +- include/app_common.h | 411 +++ include/app_control.h | 877 ++++++ include/app_control_internal.h | 95 + include/app_i18n.h | 22 +- include/{app_private.h => app_internal.h} | 37 +- include/app_preference.h | 176 +- include/app_preference_internal.h | 152 + include/app_preference_log.h | 92 + include/app_preference_private.h | 52 - include/app_service.h | 672 ----- include/app_service_private.h | 37 - include/app_storage.h | 226 -- include/app_storage_private.h | 60 - include/app_types.h | 52 + include/app_ui_notification.h | 459 --- packaging/capi-appfw-application.spec | 41 +- preference/CMakeLists.txt | 66 + preference/preference.c | 1533 ++++++++++ src/preference.c => preference/preference_db.c | 313 ++- preference/preference_inoti.c | 432 +++ src/app_device.c | 55 +- src/app_main.c | 467 +++- src/app_resource.c | 190 +- src/i18n.c | 5 - src/service.c | 1232 -------- src/storage.c | 397 --- src/storage_internal.c | 79 - src/storage_sdcard.c | 125 - src/storage_usbhost.c | 125 - src/ui_notification.c | 1115 -------- 74 files changed, 12449 insertions(+), 5486 deletions(-) mode change 100755 => 100644 AUTHORS mode change 100755 => 100644 LICENSE create mode 100755 TC/_export_env.sh create mode 100755 TC/_export_target_env.sh create mode 100755 TC/build.sh create mode 100755 TC/clean.sh create mode 100755 TC/config create mode 100755 TC/execute.sh create mode 100755 TC/testcase/Makefile create mode 100755 TC/testcase/tslist create mode 100755 TC/testcase/utc_alarm.c create mode 100755 TC/testcase/utc_app.c create mode 100755 TC/testcase/utc_i18n.c create mode 100755 TC/testcase/utc_preference.c create mode 100755 TC/testcase/utc_service.c create mode 100755 TC/tet_scen create mode 100755 TC/tetbuild.cfg create mode 100755 TC/tetclean.cfg create mode 100755 TC/tetexec.cfg create mode 100644 alarm/CMakeLists.txt rename {src => alarm}/alarm.c (74%) mode change 100755 => 100644 create mode 100644 app_common/CMakeLists.txt rename {src => app_common}/app_error.c (86%) create mode 100644 app_common/app_event.c rename {src => app_common}/app_finalizer.c (87%) rename {src => app_common}/app_package.c (81%) create mode 100755 app_common/app_path.c create mode 100644 app_control/CMakeLists.txt create mode 100755 app_control/app_control.c create mode 100644 capi-appfw-application.manifest rename capi-appfw-application.pc.in => capi-appfw-module.pc.in (90%) create mode 100755 doc/appfw_alarm_doc.h create mode 100755 doc/appfw_app_common_doc.h create mode 100755 doc/appfw_app_control_doc.h create mode 100755 doc/appfw_app_doc.h create mode 100755 doc/appfw_i18n_doc.h create mode 100755 doc/appfw_preference_doc.h create mode 100755 doc/images/capi_appfw_application_lifecycle.png create mode 100755 doc/images/capi_appfw_application_package.png create mode 100755 doc/images/capi_appfw_application_states.png create mode 100644 include/app_common.h create mode 100755 include/app_control.h create mode 100644 include/app_control_internal.h rename include/{app_private.h => app_internal.h} (76%) create mode 100755 include/app_preference_internal.h create mode 100755 include/app_preference_log.h delete mode 100755 include/app_preference_private.h delete mode 100755 include/app_service.h delete mode 100755 include/app_service_private.h delete mode 100644 include/app_storage.h delete mode 100755 include/app_storage_private.h create mode 100644 include/app_types.h delete mode 100755 include/app_ui_notification.h create mode 100644 preference/CMakeLists.txt create mode 100755 preference/preference.c rename src/preference.c => preference/preference_db.c (58%) create mode 100755 preference/preference_inoti.c delete mode 100755 src/service.c delete mode 100755 src/storage.c delete mode 100755 src/storage_internal.c delete mode 100755 src/storage_sdcard.c delete mode 100755 src/storage_usbhost.c delete mode 100755 src/ui_notification.c diff --git a/AUTHORS b/AUTHORS old mode 100755 new mode 100644 diff --git a/CMakeLists.txt b/CMakeLists.txt index 72efefe..9c346a9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(requires "dlog bundle appcore-common appcore-efl aul ail appsvc notification elementary capi-base-common alarm-service sqlite3") -SET(pc_requires "capi-base-common") +SET(requires "dlog bundle appcore-common appcore-efl aul elementary capi-base-common vconf-internal-keys") +SET(pc_requires "capi-base-common capi-appfw-app-control capi-appfw-app-common") INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${requires}) @@ -28,12 +28,21 @@ ENDIF("${ARCH}" STREQUAL "arm") ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") ADD_DEFINITIONS("-DSLP_DEBUG") -SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") +IF(_APPFW_FEATURE_PROCESS_POOL) + ADD_DEFINITIONS("-D_APPFW_FEATURE_PROCESS_POOL") +ENDIF(_APPFW_FEATURE_PROCESS_POOL) + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib -Wl,--no-undefined") aux_source_directory(src SOURCES) ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) -TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) +ADD_SUBDIRECTORY(app_control) +ADD_SUBDIRECTORY(app_common) +ADD_SUBDIRECTORY(alarm) +ADD_SUBDIRECTORY(preference) + +TARGET_LINK_LIBRARIES(${fw_name} capi-appfw-app-control capi-appfw-app-common ${${fw_name}_LDFLAGS}) SET_TARGET_PROPERTIES(${fw_name} PROPERTIES @@ -55,7 +64,7 @@ SET(PC_REQUIRED ${pc_requires}) SET(PC_LDFLAGS -l${fw_name}) CONFIGURE_FILE( - capi-appfw-application.pc.in + capi-appfw-module.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc @ONLY ) diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/TC/_export_env.sh b/TC/_export_env.sh new file mode 100755 index 0000000..72a11ec --- /dev/null +++ b/TC/_export_env.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +. ./config +export TET_INSTALL_PATH=$TET_INSTALL_HOST_PATH # tetware root path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target # tetware target path +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH diff --git a/TC/_export_target_env.sh b/TC/_export_target_env.sh new file mode 100755 index 0000000..5ddaa53 --- /dev/null +++ b/TC/_export_target_env.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ./config +export TET_INSTALL_PATH=$TET_INSTALL_TARGET_PATH # path to path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH diff --git a/TC/build.sh b/TC/build.sh new file mode 100755 index 0000000..72aad6c --- /dev/null +++ b/TC/build.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -c -p ./ +tcc -b -j $JOURNAL_RESULT -p ./ +grw -c 7 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/clean.sh b/TC/clean.sh new file mode 100755 index 0000000..29743e0 --- /dev/null +++ b/TC/clean.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +RESULT_DIR=results + +tcc -c -p ./ # executing tcc, with clean option (-c) +rm -r $RESULT_DIR +rm -r tet_tmp_dir +rm testcase/tet_captured diff --git a/TC/config b/TC/config new file mode 100755 index 0000000..6761a8b --- /dev/null +++ b/TC/config @@ -0,0 +1,2 @@ +TET_INSTALL_HOST_PATH=/home/junghyuk/workspace/TETware +TET_INSTALL_TARGET_PATH=/mnt/nfs/workspace/TETware diff --git a/TC/execute.sh b/TC/execute.sh new file mode 100755 index 0000000..a4f6095 --- /dev/null +++ b/TC/execute.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. ./_export_target_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -e -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/testcase/Makefile b/TC/testcase/Makefile new file mode 100755 index 0000000..ae77b83 --- /dev/null +++ b/TC/testcase/Makefile @@ -0,0 +1,24 @@ +CC ?= gcc + +C_FILES = $(shell ls *.c) + +PKGS = capi-appfw-application capi-base-common dlog gthread-2.0 gobject-2.0 + +LDFLAGS = `pkg-config --libs $(PKGS)` +LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s + +CFLAGS = -I. `pkg-config --cflags $(PKGS)` +CFLAGS += -I$(TET_ROOT)/inc/tet3 +CFLAGS += -Wall + +TCS := $(shell ls -1 *.c | cut -d. -f1) + +all: $(TCS) + +%: %.c + $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS) + +clean: + rm -f $(TCS) diff --git a/TC/testcase/tslist b/TC/testcase/tslist new file mode 100755 index 0000000..064372a --- /dev/null +++ b/TC/testcase/tslist @@ -0,0 +1,7 @@ +/testcase/utc_app +/testcase/utc_service +/testcase/utc_i18n +/testcase/utc_preference +/testcase/utc_alarm + + diff --git a/TC/testcase/utc_alarm.c b/TC/testcase/utc_alarm.c new file mode 100755 index 0000000..8bc068d --- /dev/null +++ b/TC/testcase/utc_alarm.c @@ -0,0 +1,766 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include + +static int passed =1; +int tid; +GMainLoop *loop; + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_alarm_schedule_after_delay_positive(void); +static void utc_alarm_schedule_after_delay_negative(void); +static void utc_alarm_cancel_positive(void); +static void utc_alarm_cancel_negative(void); +static void utc_alarm_cancel_all_positive(void); +static void utc_alarm_foreach_registered_alarm_positive(void); +static void utc_alarm_foreach_registered_alarm_negative(void); +static void utc_alarm_get_scheduled_date_positive(void); +static void utc_alarm_get_scheduled_date_negative(void); +static void utc_alarm_get_scheduled_period_positive(void); +static void utc_alarm_get_scheduled_period_negative(void); +static void utc_alarm_schedule_at_date_positive(void); +static void utc_alarm_schedule_at_date_negative(void); +static void utc_alarm_schedule_with_recurrence_week_flag_positive(void); +static void utc_alarm_schedule_with_recurrence_week_flag_negative(void); +static void utc_alarm_get_scheduled_recurrence_week_flag_positive(void); +static void utc_alarm_get_scheduled_recurrence_week_flag_negative(void); +static void utc_alarm_get_current_time_positive(void); +static void utc_alarm_get_current_time_negative(void); +static void utc_alarm_get_app_control_positive(void); +static void utc_alarm_get_app_control_negative(void); + + + +struct tet_testlist tet_testlist[] = { + { utc_alarm_schedule_after_delay_positive, 1 }, + { utc_alarm_schedule_after_delay_negative, 2 }, + { utc_alarm_cancel_positive, 1 }, + { utc_alarm_cancel_negative, 2 }, + { utc_alarm_cancel_all_positive, 1 }, + { utc_alarm_foreach_registered_alarm_positive, 1 }, + { utc_alarm_foreach_registered_alarm_negative, 2 }, + { utc_alarm_get_scheduled_date_positive, 1 }, + { utc_alarm_get_scheduled_date_negative, 2 }, + { utc_alarm_get_scheduled_period_positive, 1 }, + { utc_alarm_get_scheduled_period_negative, 2 }, + { utc_alarm_schedule_at_date_positive, 1 }, + { utc_alarm_schedule_at_date_negative, 2 }, + { utc_alarm_schedule_with_recurrence_week_flag_positive, 1 }, + { utc_alarm_schedule_with_recurrence_week_flag_negative, 2 }, + { utc_alarm_get_scheduled_recurrence_week_flag_positive, 1 }, + { utc_alarm_get_scheduled_recurrence_week_flag_negative, 2 }, + { utc_alarm_get_current_time_positive, 1 }, + { utc_alarm_get_current_time_negative, 2 }, + { utc_alarm_get_app_control_positive, 1 }, + { utc_alarm_get_app_control_negative, 2 }, + { NULL, 0 }, +}; + +static void startup(void) +{ + /* start of TC */ + g_type_init(); +} + +static void cleanup(void) +{ + /* end of TC */ + alarm_cancel_all(); +} + +static bool foreach_alarm_cb(int alarm, void* user_data) +{ + if(alarm == tid) + { + dts_pass("utc_alarm_foreach_registered_alarm_positive"); + } + + dts_message("utc_alarm_foreach_registered_alarm_positive", "registered id = %d callback id = %d", alarm, tid); + + return true; +} + +static gboolean timeout(gpointer data) +{ + printf("timeout called\n"); + g_main_loop_quit(data); + return FALSE; +} + +/** + * @brief Positive test case of alarm_schedule_after_delay() + */ +static void utc_alarm_schedule_after_delay_positive(void) +{ + time_t current_time; + struct tm current_tm; + app_control_h app_control; + int tid; + GMainLoop *loop; + int ret = ALARM_ERROR_NONE; + + app_control_create(&app_control); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + app_control_set_package(app_control, "org.tizen.memo"); + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(5000,timeout , loop); + + ret = alarm_schedule_after_delay(app_control, 1, 1, &tid); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_schedule_after_delay_positive", "passed"); + } + else + { + dts_fail("utc_alarm_schedule_after_delay_positive", "failed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); +} + +/** + * @brief Negative test case of alarm_schedule_after_delay() + */ +static void utc_alarm_schedule_after_delay_negative(void) +{ + time_t current_time; + struct tm current_tm; + app_control_h app_control; + int ret = ALARM_ERROR_NONE; + int tid; + GMainLoop *loop; + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + + ret = alarm_schedule_after_delay(app_control, 1, 1, NULL); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_schedule_after_delay_negative", "failed"); + } + else + { + dts_pass("utc_alarm_schedule_after_delay_negative", "passed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + + +/** + * @brief Positive test case of alarm_cancel() + */ +static void utc_alarm_cancel_positive(void) +{ + time_t current_time; + struct tm current_tm; + app_control_h app_control; + int ret = ALARM_ERROR_NONE; + int tid; + GMainLoop *loop; + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(5000,timeout , loop); + + ret = alarm_schedule_after_delay(app_control, 1, 1, &tid); + ret = alarm_cancel(tid); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_cancel_positive", "passed"); + } + else + { + dts_fail("utc_alarm_cancel_positive", "passed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); +} + +/** + * @brief Negative test case of alarm_cancel() + */ +static void utc_alarm_cancel_negative(void) +{ + int ret = ALARM_ERROR_NONE; + + ret = alarm_cancel(NULL); + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_cancel_negative", "failed"); + } + else + { + dts_pass("utc_alarm_cancel_negative", "passed"); + } + alarm_cancel_all(); +} + +/** + * @brief Positive test case of alarm_cancel_all() + */ +static void utc_alarm_cancel_all_positive(void) +{ + int ret = ALARM_ERROR_NONE; + + ret = alarm_cancel_all(); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_cancel_all_positive", "passed"); + } + else + { + dts_fail("utc_alarm_cancel_all_positive", "failed"); + } + + alarm_cancel_all(); + +} + + +/** + * @brief Positive test case of alarm_foreach_registered_alarm() + */ +static void utc_alarm_foreach_registered_alarm_positive(void) +{ + int ret = ALARM_ERROR_NONE; + time_t current_time; + struct tm current_tm; + app_control_h app_control; + int tid; + GMainLoop *loop; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(1000,timeout , loop); + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + alarm_schedule_after_delay(app_control, 1, 5, &tid); + + ret = alarm_foreach_registered_alarm(foreach_alarm_cb,NULL); + + g_main_loop_run(loop); + + if(ret != ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_foreach_registered_alarm_positive", "failed"); + } + else + { + dts_pass("utc_alarm_foreach_registered_alarm_positive" , "passed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + + +/** + * @brief Negative test case of alarm_foreach_registered_alarm() + */ +static void utc_alarm_foreach_registered_alarm_negative(void) +{ + int ret = ALARM_ERROR_NONE; + + // do i need to call alarm_init?? + ret = alarm_foreach_registered_alarm(NULL,NULL); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_foreach_registered_alarm_negative", "failed"); + } + else + { + dts_pass("utc_alarm_foreach_registered_alarm_negative", "passed"); + } + alarm_cancel_all(); +} + + +/** + * @brief Positive test case of alarm_get_scheduled_date() + */ +static void utc_alarm_get_scheduled_date_positive(void) +{ + struct tm date; + app_control_h app_control; + int ret = ALARM_ERROR_NONE; + int tid; + GMainLoop *loop; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(5000,timeout , loop); + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + alarm_schedule_after_delay(app_control, 1, 5, &tid); + + ret = alarm_get_scheduled_date(tid, &date); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_get_date_positive", "passed"); + } + else + { + dts_fail("utc_alarm_get_date_positive", "failed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); +} + +/** + * @brief Negative test case of alarm_get_scheduled_date() + */ +static void utc_alarm_get_scheduled_date_negative(void) +{ + struct tm date; + int ret = ALARM_ERROR_NONE; + + ret = alarm_get_scheduled_date(NULL, &date); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_scheduled_date_negative", "failed"); + } + else + { + dts_pass("utc_alarm_get_scheduled_date_negative", "passed"); + } + alarm_cancel_all(); +} + + +/** + * @brief Positive test case of alarm_get_period() + */ +static void utc_alarm_get_scheduled_period_positive(void) +{ + time_t current_time; + struct tm current_tm; + app_control_h app_control; + int ret = ALARM_ERROR_NONE; + int period = 0; + int tid; + GMainLoop *loop; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(1000,timeout , loop); + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + alarm_schedule_after_delay(app_control, 1, 1, &tid); + + ret = alarm_get_scheduled_period(tid, &period); + + g_main_loop_run(loop); + + if(ret != ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_scheduled_period_positive", "failed"); + } + + if(period == 1) + { + dts_pass("utc_alarm_get_scheduled_period_positive", "passed"); + } + else + { + dts_fail("utc_alarm_get_scheduled_period_positive", "failed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + +/** + * @brief Negative test case of alarm_get_scheduled_period() + */ +static void utc_alarm_get_scheduled_period_negative(void) +{ + time_t current_time; + struct tm current_tm; + int ret = ALARM_ERROR_NONE; + int period = 0; + int tid; + GMainLoop *loop; + + ret = alarm_get_scheduled_period(NULL,&period); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_scheduled_period_negative", "failed"); + } + else + { + dts_pass("utc_alarm_get_scheduled_period_negative", "passed"); + } + + alarm_cancel_all(); + +} + +/** + * @brief Positive test case of alarm_schedule_at_date() + */ +static void utc_alarm_schedule_at_date_positive(void) +{ + time_t current_time; + struct tm date; + time_t now; + app_control_h app_control; + int tid; + GMainLoop *loop; + + int ret = ALARM_ERROR_NONE; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(5000,timeout , loop); + + time(&now); + localtime_r(&now, &date); + + date.tm_sec += 3; + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + + ret = alarm_schedule_at_date(app_control, &date, 2, &tid); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_schedule_at_date_positive", "passed"); + + } + else + { + dts_fail("utc_alarm_schedule_at_date_positive", "failed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + + +/** + * @brief Negative test case of alarm_schedule_at_date() + */ +static void utc_alarm_schedule_at_date_negative(void) +{ + time_t current_time; + struct tm current_tm; + int ret = ALARM_ERROR_NONE; + app_control_h app_control; + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + ret = alarm_schedule_at_date(app_control, NULL, 1, &tid); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_schedule_at_date_negative", "failed"); + } + else + { + dts_pass("utc_alarm_schedule_at_date_negative", "passed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + +/** + * @brief Negative test case of alarm_schedule_at_date() + */ +static void utc_alarm_schedule_with_recurrence_week_flag_positive(void) +{ + time_t current_time; + struct tm date; + time_t now; + app_control_h app_control; + int tid; + GMainLoop *loop; + + int ret = ALARM_ERROR_NONE; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(5000,timeout , loop); + + time(&now); + localtime_r(&now, &date); + date.tm_sec += 3; + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + + alarm_schedule_with_recurrence_week_flag(app_control, &date, ALARM_WEEK_FLAG_MONDAY, &tid); + + g_main_loop_run(loop); + + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_schedule_with_recurrence_week_flag_positive", "passed"); + } + else + { + dts_fail("utc_alarm_schedule_with_recurrence_week_flag_positive", "failed"); + } + + app_control_destory(app_control); + alarm_cancel_all(); + +} + +static void utc_alarm_schedule_with_recurrence_week_flag_negative(void) +{ + + time_t current_time; + struct tm date; + time_t now; + + int ret = ALARM_ERROR_NONE; + + time(&now); + localtime_r(&now, &date); + date.tm_sec += 3; + + ret = alarm_schedule_with_recurrence_week_flag(NULL, &date, ALARM_WEEK_FLAG_MONDAY, &tid); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_schedule_at_date_negative", "failed"); + } + else + { + dts_pass("utc_alarm_schedule_at_date_negative", "passed"); + } + + alarm_cancel_all(); + +} + + +/** + * @brief Negative test case of alarm_schedule_at_date() + */ +static void utc_alarm_get_scheduled_recurrence_week_flag_positive(void) +{ + time_t current_time; + struct tm date; + time_t now; + app_control_h app_control; + int tid; + GMainLoop *loop; + int week_flag = 0; + + int ret = ALARM_ERROR_NONE; + + time(&now); + localtime_r(&now, &date); + date.tm_sec += 3; + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + + alarm_schedule_with_recurrence_week_flag(app_control, &date, ALARM_WEEK_FLAG_MONDAY, &tid); + + alarm_get_scheduled_recurrence_week_flag(tid, &week_flag); + + + if(ret != ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_scheduled_recurrence_week_flag_positive", "failed"); + } + + if(week_flag == ALARM_WEEK_FLAG_MONDAY) + { + dts_pass("utc_alarm_get_scheduled_recurrence_week_flag_positive", "passed"); + } + else + { + dts_fail("utc_alarm_get_scheduled_recurrence_week_flag_positive", "failed"); + } + app_control_destory(app_control); + alarm_cancel_all(); + +} + +static void utc_alarm_get_scheduled_recurrence_week_flag_negative(void) +{ + + time_t current_time; + struct tm date; + time_t now; + + int ret = ALARM_ERROR_NONE; + + ret = alarm_get_scheduled_recurrence_week_flag(NULL ,NULL); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_scheduled_recurrence_week_flag_negative", "failed"); + } + else + { + dts_pass("utc_alarm_get_scheduled_recurrence_week_flag_negative", "passed"); + } + + alarm_cancel_all(); + +} + +static void utc_alarm_get_current_time_positive(void) +{ + struct tm date; + int ret = ALARM_ERROR_NONE; + + ret = alarm_get_current_time(&date); + if(ret == ALARM_ERROR_NONE) + { + dts_pass("utc_alarm_get_current_time_positive", "passed"); + } + else + { + dts_fail("utc_alarm_get_current_time_positive", "failed"); + } +} + +static void utc_alarm_get_current_time_negative(void) +{ + int ret = ALARM_ERROR_NONE; + + ret = alarm_get_current_time(NULL); + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_current_time_negative", "failed"); + } + else + { + dts_pass("utc_alarm_get_current_time_negative", "passed"); + } +} + +static void utc_alarm_get_app_control_positive(void) +{ + time_t current_time; + struct tm current_tm; + app_control_h app_control; + app_control_h app_control_return; + + int ret = ALARM_ERROR_NONE; + int tid; + GMainLoop *loop; + char *package; + + loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(1000,timeout , loop); + + app_control_create(&app_control); + app_control_set_package(app_control, "org.tizen.memo"); + app_control_set_operation(app_control, SERVICE_OPERATION_DEFAULT); + alarm_schedule_after_delay(app_control, 3, 0, &tid); + + ret = alarm_get_app_control(tid, &app_control_return); + + g_main_loop_run(loop); + + if(ret != ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_app_control_positive", "failed"); + } + + ret = app_control_get_package(app_control_return, &package); + + if(ret != SERVICE_ERROR_NONE) + { + dts_fail("utc_alarm_get_app_control_positive", "failed"); + } + + if(!strcmp(package, "org.tizen.memo")) + { + dts_pass("utc_alarm_get_app_control_positive", "passed"); + } + else + { + dts_fail("utc_alarm_get_app_control_positive", "failed"); + } + + if(package != NULL) + { + free(package); + } + app_control_destory(app_control); + app_control_destory(app_control_return); + alarm_cancel_all(); + +} +static void utc_alarm_get_app_control_negative(void) +{ + int ret = ALARM_ERROR_NONE; + + ret = alarm_get_app_control(NULL,NULL); + + if(ret == ALARM_ERROR_NONE) + { + dts_fail("utc_alarm_get_app_control_negative", "failed"); + } + else + { + dts_pass("utc_alarm_get_app_control_negative", "passed"); + } +} + diff --git a/TC/testcase/utc_app.c b/TC/testcase/utc_app.c new file mode 100755 index 0000000..e012ed1 --- /dev/null +++ b/TC/testcase/utc_app.c @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include +#include + +static void startup(void); +static void cleanup(void); + + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; +static main_loop_flag = 0; + +static void utc_app_get_package_negative1(void); +static void utc_app_get_package_negative2(void); +static void utc_app_get_name_negative1(void); +static void utc_app_get_name_negative2(void); +static void utc_app_get_id_negative1(void); +static void utc_app_get_id_negative2(void); +static void utc_app_get_version_negative1(void); +static void utc_app_get_version_negative2(void); +static void utc_app_get_resource_negative1(void); +static void utc_app_get_resource_negative2(void); +static void utc_app_get_data_directory_negative1(void); +static void utc_app_get_data_directory_negative2(void); +static void utc_app_get_device_orientation_positive(void); +static void utc_app_set_reclaiming_system_cache_on_pause_positive1(void); +static void utc_app_set_reclaiming_system_cache_on_pause_positive2(void); +static void utc_app_efl_main_negative1(void); +static void utc_app_efl_main_negative2(void); +static void utc_app_efl_exit_negative(void); + +struct tet_testlist tet_testlist[] = { + { utc_app_get_package_negative1, 1 }, + { utc_app_get_package_negative2, 1 }, + { utc_app_get_name_negative1, 1 }, + { utc_app_get_name_negative2, 1 }, + { utc_app_get_id_negative1, 1 }, + { utc_app_get_id_negative2, 1 }, + { utc_app_get_version_negative1, 1 }, + { utc_app_get_version_negative2, 1 }, + { utc_app_get_resource_negative1, 1 }, + { utc_app_get_resource_negative2, 1 }, + { utc_app_get_data_directory_negative1, 1 }, + { utc_app_get_data_directory_negative2, 1 }, + { utc_app_get_device_orientation_positive, 1 }, + { utc_app_set_reclaiming_system_cache_on_pause_positive1, 1 }, + { utc_app_set_reclaiming_system_cache_on_pause_positive2, 1 }, + { utc_app_efl_main_negative1, 1}, + { utc_app_efl_main_negative2, 1}, + { utc_app_efl_exit_negative, 1}, + { NULL, 0 }, +}; + +static void startup(void) +{ + /* start of TC */ +} + +static void cleanup(void) +{ + /* end of TC */ +} + +static void utc_app_get_package_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + char *package = NULL; + + ret = app_get_package(&package); + + dts_message(API_NAME, "ret(%d), package(%s)", ret, package); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_package_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + ret = app_get_package(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_name_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + char *name = NULL; + + ret = app_get_name(&name); + + dts_message(API_NAME, "ret(%d), name(%s)", ret, name); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + +static void utc_app_get_name_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + ret = app_get_name(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_version_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + char *version = NULL; + + ret = app_get_version(&version); + + dts_message(API_NAME, "ret(%d), version(%s)", ret, version); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_version_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + ret = app_get_version(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_resource_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + char *ret = NULL; + char *path = NULL; + int size = 0; + + ret = app_get_resource("res/image.jpg", path, size); + + dts_message(API_NAME, "ret(%s), path(%s)", ret, path); + + if(path != NULL) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_resource_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + char *ret = NULL; + int size = 0; + + ret = app_get_resource("res/image.jpg", NULL, size); + + dts_message(API_NAME, "ret(%s)", ret); + + if(ret != NULL) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_data_directory_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + char *ret = NULL; + char *path = NULL; + int size =0; + + ret = app_get_data_directory(path, size); + + dts_message(API_NAME, "ret(%s), path(%s)", ret, path); + + if(ret != NULL) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + + +static void utc_app_get_data_directory_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + char *ret = NULL; + int size = 0; + + ret = app_get_data_directory(NULL, size); + + dts_message(API_NAME, "ret(%s)", ret); + + if(ret != NULL) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + +static void utc_app_get_device_orientation_positive(void) +{ + const char *API_NAME = __FUNCTION__; + + app_device_orientation_e orientation = APP_DEVICE_ORIENTATION_0; + + orientation = app_get_device_orientation(); + + dts_message(API_NAME, "orientation(%d)", orientation); + + dts_pass(__FUNCTION__, "passed"); +} + +static void utc_app_set_reclaiming_system_cache_on_pause_positive1(void) +{ + const char *API_NAME = __FUNCTION__; + + app_set_reclaiming_system_cache_on_pause(true); + + dts_pass(API_NAME, "passed"); +} + +static void utc_app_set_reclaiming_system_cache_on_pause_positive2(void) +{ + const char *API_NAME = __FUNCTION__; + + app_set_reclaiming_system_cache_on_pause(false); + + dts_pass(API_NAME, "passed"); +} + +static void utc_app_get_id_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + char *id = NULL; + + ret = app_get_id(&id); + + dts_message(API_NAME, "ret(%d), id(%s)", ret, id); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + +static void utc_app_get_id_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + ret = app_get_id(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == APP_ERROR_NONE) + { + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + +static bool _app_create(void *user_data) +{ + main_loop_flag = 1; + return true; +} + +static void _app_pause(void *user_data) +{ +} + +static void _app_resume(void *user_data) +{ +} + +static void _app_terminate(void *user_data) +{ + main_loop_flag = 0; +} + +static void _app_control(app_control_h app_control, void *user_data) +{ +} + +static void utc_app_efl_main_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + app_event_callback_s event_callback = {0,}; + int argc = 3; + char *argv[4] = {"package", "appid", "exec", NULL}; + int ret = APP_ERROR_NONE; + event_callback.create = _app_create; + event_callback.app_control = _app_control; + event_callback.terminate = _app_terminate; + event_callback.pause = _app_pause; + event_callback.resume = _app_resume; + + ret = app_efl_main(&argc, &argv, &event_callback, NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret != APP_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + app_efl_exit(); + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_efl_main_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = APP_ERROR_NONE; + + ret = app_efl_main(NULL, NULL, NULL, NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == APP_ERROR_NONE) + { + app_efl_exit(); + dts_fail(API_NAME, "failed"); + } + else + { + dts_pass(API_NAME, "passed"); + } +} + +static void utc_app_efl_exit_negative(void) +{ + const char *API_NAME = __FUNCTION__; + app_event_callback_s event_callback = {0,}; + int argc = 3; + char *argv[4] = {"package", "appid", "exec", NULL}; + int ret = APP_ERROR_NONE; + event_callback.create = _app_create; + event_callback.app_control = _app_control; + event_callback.terminate = _app_terminate; + event_callback.pause = _app_pause; + event_callback.resume = _app_resume; + + ret = app_efl_main(&argc, &argv, &event_callback, NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + app_efl_exit(); + dts_pass(API_NAME, "passed"); +} + diff --git a/TC/testcase/utc_i18n.c b/TC/testcase/utc_i18n.c new file mode 100755 index 0000000..b007811 --- /dev/null +++ b/TC/testcase/utc_i18n.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include +#include + + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_i18n_get_test_positive(void); +static void utc_i18n_get_test_negative(void); + +struct tet_testlist tet_testlist[] = { + {utc_i18n_get_test_positive, 1}, + {utc_i18n_get_test_negative, 1}, + {NULL, 0}, +}; + +static void startup(void) +{ + +} + + +static void cleanup(void) +{ + /* end of TC */ +} + +static void utc_i18n_get_test_positive(void) +{ + const char *API_NAME = __FUNCTION__; + const char *msg_id = "HELLO"; + char *msg; + + msg = i18n_get_text(msg_id); + + if (!strcmp(msg_id, msg)) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_i18n_get_test_negative(void) +{ + const char *API_NAME = __FUNCTION__; + char *msg; + + msg = i18n_get_text(NULL); + + if (msg == NULL) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + diff --git a/TC/testcase/utc_preference.c b/TC/testcase/utc_preference.c new file mode 100755 index 0000000..afe5bf6 --- /dev/null +++ b/TC/testcase/utc_preference.c @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include +#include + + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_preference_set_int_negative1(void); +static void utc_preference_set_int_negative2(void); + +static void utc_preference_set_double_negative1(void); +static void utc_preference_set_double_negative2(void); + +static void utc_preference_set_string_negative1(void); +static void utc_preference_set_string_negative2(void); + +static void utc_preference_set_boolean_negative1(void); +static void utc_preference_set_boolean_negative2(void); + +static void utc_preference_get_int_negative1(void); +static void utc_preference_get_int_negative2(void); + +static void utc_preference_get_double_negative1(void); +static void utc_preference_get_double_negative2(void); + +static void utc_preference_get_string_negative1(void); +static void utc_preference_get_string_negative2(void); + +static void utc_preference_get_boolean_negative1(void); +static void utc_preference_get_boolean_negative2(void); + +static void utc_preference_remove_negative1(void); +static void utc_preference_remove_all_negative1(void); + +static void utc_preference_is_existing_negative1(void); +static void utc_preference_is_existing_negative2(void); + +static void utc_preference_set_changed_cb_negative1(void); +static void utc_preference_set_changed_cb_negative2(void); +static void utc_preference_set_changed_cb_negative3(void); + +static void utc_preference_unset_changed_cb_negative1(void); +static void utc_preference_unset_changed_cb_negative2(void); + +static void utc_preference_foreach_item_negative1(void); + + +struct tet_testlist tet_testlist[] = { + {utc_preference_set_int_negative1, 2}, + {utc_preference_set_int_negative2, 2}, + + {utc_preference_set_double_negative1, 2}, + {utc_preference_set_double_negative2, 2}, + + {utc_preference_set_string_negative1, 2}, + {utc_preference_set_string_negative2, 2}, + + {utc_preference_set_boolean_negative1, 2}, + {utc_preference_set_boolean_negative2, 2}, + + {utc_preference_get_int_negative1, 2}, + {utc_preference_get_int_negative2, 2}, + + {utc_preference_get_double_negative1, 2}, + {utc_preference_get_double_negative2, 2}, + + {utc_preference_get_string_negative1, 2}, + {utc_preference_get_string_negative2, 2}, + + {utc_preference_get_boolean_negative1, 2}, + {utc_preference_get_boolean_negative2, 2}, + + {utc_preference_remove_negative1, 2}, + {utc_preference_remove_all_negative1, 2}, + + {utc_preference_is_existing_negative1, 2}, + {utc_preference_is_existing_negative2, 2}, + + {utc_preference_set_changed_cb_negative1, 2}, + {utc_preference_set_changed_cb_negative2, 2}, + {utc_preference_set_changed_cb_negative3, 2}, + + {utc_preference_unset_changed_cb_negative1, 2}, + {utc_preference_unset_changed_cb_negative2, 2}, + + {utc_preference_foreach_item_negative1, 2}, + + {NULL, 0}, +}; + +static void startup(void) +{ + +} + + +static void cleanup(void) +{ + /* end of TC */ +} + +static void utc_preference_set_int_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "preference_key"; + + int ret; + + ret = preference_set_int(key, 1); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_int_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_int(NULL, 1); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_double_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "preference_key"; + + int ret; + + ret = preference_set_double(key, 1.0); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_double_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_double(NULL, 1.0); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_string_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "preference_key"; + + int ret; + + ret = preference_set_string(key, "string"); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_string_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_string(NULL, "string"); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_boolean_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "preference_key"; + + int ret; + + ret = preference_set_boolean(key, true); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_boolean_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_boolean(NULL, true); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + + +static void utc_preference_get_int_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int value; + + int ret; + + ret = preference_get_int(NULL, &value); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_int_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "key"; + + int ret; + + ret = preference_get_int(key, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_double_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + double value; + + int ret; + + ret = preference_get_double(NULL, &value); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_double_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "key"; + + int ret; + + ret = preference_get_double(key, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_string_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + char *value; + + int ret; + + ret = preference_get_string(NULL, &value); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_string_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "key"; + + int ret; + + ret = preference_get_string(key, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_boolean_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + bool value; + + int ret; + + ret = preference_get_boolean(NULL, &value); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_get_boolean_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + const char *key = "key"; + + int ret; + + ret = preference_get_boolean(key, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_remove_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_remove(NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_remove_all_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_remove_all(); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_is_existing_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + bool is_exist; + + int ret; + + ret = preference_is_existing(NULL,&is_exist); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_is_existing_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_is_existing("key", NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void dts_preference_changed_cb(const char *key, void *user_data) +{ + +} + +static void utc_preference_set_changed_cb_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_changed_cb(NULL, dts_preference_changed_cb, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_changed_cb_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_changed_cb("key", NULL, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_set_changed_cb_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_set_changed_cb("key", dts_preference_changed_cb, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_unset_changed_cb_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_unset_changed_cb(NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_unset_changed_cb_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_unset_changed_cb("key"); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_preference_foreach_item_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + + int ret; + + ret = preference_foreach_item(NULL, NULL); + + if (ret != PREFERENCE_ERROR_NONE) { + dts_pass(API_NAME, "passed"); + } else { + dts_fail(API_NAME, "failed"); + } +} + diff --git a/TC/testcase/utc_service.c b/TC/testcase/utc_service.c new file mode 100755 index 0000000..cb0b276 --- /dev/null +++ b/TC/testcase/utc_service.c @@ -0,0 +1,2948 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include +#include +#include +#include + +static void startup(void); +static void cleanup(void); + + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_app_control_create_positive(void); +static void utc_app_control_create_negative(void); + +static void utc_app_control_destroy_positive(void); +static void utc_app_control_destroy_negative(void); + +static void utc_app_control_set_operation_positive1(void); +static void utc_app_control_set_operation_positive2(void); +static void utc_app_control_set_operation_negative(void); + +static void utc_app_control_get_operation_positive(void); +static void utc_app_control_get_operation_negative1(void); +static void utc_app_control_get_operation_negative2(void); +static void utc_app_control_get_operation_negative3(void); + +static void utc_app_control_set_uri_positive1(void); +static void utc_app_control_set_uri_positive2(void); +static void utc_app_control_set_uri_negative(void); + +static void utc_app_control_get_uri_positive(void); +static void utc_app_control_get_uri_negative1(void); +static void utc_app_control_get_uri_negative2(void); +static void utc_app_control_get_uri_negative3(void); + +static void utc_app_control_set_mime_positive1(void); +static void utc_app_control_set_mime_positive2(void); +static void utc_app_control_set_mime_negative(void); + +static void utc_app_control_get_mime_positive(void); +static void utc_app_control_get_mime_negative1(void); +static void utc_app_control_get_mime_negative2(void); +static void utc_app_control_get_mime_negative3(void); + +static void utc_app_control_set_package_positive(void); +static void utc_app_control_set_package_negative1(void); +static void utc_app_control_set_package_negative2(void); + +static void utc_app_control_get_package_positive(void); +static void utc_app_control_get_package_negative1(void); +static void utc_app_control_get_package_negative2(void); +static void utc_app_control_get_package_negative3(void); + +static void utc_app_control_set_app_id_positive(void); +static void utc_app_control_set_app_id_negative1(void); +static void utc_app_control_set_app_id_negative2(void); + +static void utc_app_control_get_app_id_positive(void); +static void utc_app_control_get_app_id_negative1(void); +static void utc_app_control_get_app_id_negative2(void); +static void utc_app_control_get_app_id_negative3(void); + +static void utc_app_control_set_category_positive(void); +static void utc_app_control_set_category_negative1(void); +static void utc_app_control_set_category_negative2(void); + +static void utc_app_control_get_category_positive(void); +static void utc_app_control_get_category_negative1(void); +static void utc_app_control_get_category_negative2(void); +static void utc_app_control_get_category_negative3(void); + +static void utc_app_control_set_window_positive(void); +static void utc_app_control_set_window_negative1(void); +static void utc_app_control_set_window_negative2(void); + +static void utc_app_control_get_window_positive(void); +static void utc_app_control_get_window_negative1(void); +static void utc_app_control_get_window_negative2(void); +static void utc_app_control_get_window_negative3(void); + +static void utc_app_control_add_extra_data_positive(void); +static void utc_app_control_add_extra_data_negative1(void); +static void utc_app_control_add_extra_data_negative2(void); + +static void utc_app_control_remove_extra_data_positive(void); +static void utc_app_control_remove_extra_data_negative1(void); +static void utc_app_control_remove_extra_data_negative2(void); +static void utc_app_control_remove_extra_data_negative3(void); + +static void utc_app_control_get_extra_data_positive(void); +static void utc_app_control_get_extra_data_negative1(void); +static void utc_app_control_get_extra_data_negative2(void); +static void utc_app_control_get_extra_data_negative3(void); +static void utc_app_control_get_extra_data_negative4(void); + +static void utc_app_control_foreach_extra_data_positive(void); +static void utc_app_control_foreach_extra_data_negative1(void); +static void utc_app_control_foreach_extra_data_negative2(void); + +static void utc_app_control_clone_positive(void); +static void utc_app_control_clone_negative1(void); +static void utc_app_control_clone_negative2(void); + +static void utc_app_control_send_launch_request_positive1(void); +static void utc_app_control_send_launch_request_positive2(void); +static void utc_app_control_send_launch_request_positive3(void); +static void utc_app_control_send_launch_request_negative1(void); +static void utc_app_control_send_launch_request_negative2(void); + +static void utc_app_control_reply_to_launch_request_negative1(void); +static void utc_app_control_reply_to_launch_request_negative2(void); + +static void utc_app_control_foreach_app_matched_positive(void); +static void utc_app_control_foreach_app_matched_negative1(void); +static void utc_app_control_foreach_app_matched_negative2(void); + +static void utc_app_control_add_extra_data_array_positive(void); +static void utc_app_control_add_extra_data_array_negative1(void); +static void utc_app_control_add_extra_data_array_negative2(void); +static void utc_app_control_add_extra_data_array_negative3(void); + +static void utc_app_control_get_extra_data_array_positive(void); +static void utc_app_control_get_extra_data_array_negative1(void); +static void utc_app_control_get_extra_data_array_negative2(void); +static void utc_app_control_get_extra_data_array_negative3(void); +static void utc_app_control_get_extra_data_array_negative4(void); +static void utc_app_control_get_extra_data_array_negative5(void); + +static void utc_app_control_is_extra_data_array_positive(void); +static void utc_app_control_is_extra_data_array_negative1(void); +static void utc_app_control_is_extra_data_array_negative2(void); +static void utc_app_control_is_extra_data_array_negative3(void); +static void utc_app_control_is_extra_data_array_negative4(void); + + +static void utc_app_control_is_reply_requested_positive1(void); +static void utc_app_control_is_reply_requested_negative1(void); +static void utc_app_control_is_reply_requested_negative2(void); +static void utc_app_control_is_reply_requested_negative3(void); + +static void utc_app_control_get_caller_positive1(void); +static void utc_app_control_get_caller_negative1(void); +static void utc_app_control_get_caller_negative2(void); +static void utc_app_control_get_caller_negative3(void); + +static void utc_app_control_to_bundle_positive1(void); +static void utc_app_control_to_bundle_negative1(void); +static void utc_app_control_to_bundle_negative2(void); +static void utc_app_control_to_bundle_negative3(void); + + +struct tet_testlist tet_testlist[] = { + { utc_app_control_create_positive, 1 }, + { utc_app_control_create_negative, 1 }, + { utc_app_control_destroy_positive, 1 }, + { utc_app_control_destroy_negative, 1 }, + { utc_app_control_set_operation_positive1, 1 }, + { utc_app_control_set_operation_positive2, 1 }, + { utc_app_control_set_operation_negative, 1 }, + { utc_app_control_get_operation_positive, 1 }, + { utc_app_control_get_operation_negative1, 1 }, + { utc_app_control_get_operation_negative2, 1 }, + { utc_app_control_get_operation_negative3, 1 }, + { utc_app_control_set_uri_positive1, 1 }, + { utc_app_control_set_uri_positive2, 1 }, + { utc_app_control_set_uri_negative, 1 }, + { utc_app_control_get_uri_positive, 1 }, + { utc_app_control_get_uri_negative1, 1 }, + { utc_app_control_get_uri_negative2, 1 }, + { utc_app_control_get_uri_negative3, 1 }, + { utc_app_control_set_mime_positive1, 1 }, + { utc_app_control_set_mime_positive2, 1 }, + { utc_app_control_set_mime_negative, 1 }, + { utc_app_control_get_mime_positive, 1 }, + { utc_app_control_get_mime_negative1, 1 }, + { utc_app_control_get_mime_negative2, 1 }, + { utc_app_control_get_mime_negative3, 1 }, + { utc_app_control_set_package_positive, 1 }, + { utc_app_control_set_package_negative1, 1 }, + { utc_app_control_set_package_negative2, 1 }, + { utc_app_control_get_package_positive, 1 }, + { utc_app_control_get_package_negative1, 1 }, + { utc_app_control_get_package_negative2, 1 }, + { utc_app_control_get_package_negative3, 1 }, + { utc_app_control_set_app_id_positive, 1 }, + { utc_app_control_set_app_id_negative1, 1 }, + { utc_app_control_set_app_id_negative2, 1 }, + { utc_app_control_get_app_id_positive, 1 }, + { utc_app_control_get_app_id_negative1, 1 }, + { utc_app_control_get_app_id_negative2, 1 }, + { utc_app_control_get_app_id_negative3, 1 }, + { utc_app_control_set_category_positive, 1 }, + { utc_app_control_set_category_negative1, 1 }, + { utc_app_control_set_category_negative2, 1 }, + { utc_app_control_get_category_positive, 1 }, + { utc_app_control_get_category_negative1, 1 }, + { utc_app_control_get_category_negative2, 1 }, + { utc_app_control_get_category_negative3, 1 }, + { utc_app_control_set_window_positive, 1 }, + { utc_app_control_set_window_negative1, 1 }, + { utc_app_control_set_window_negative2, 1 }, + { utc_app_control_get_window_positive, 1 }, + { utc_app_control_get_window_negative1, 1 }, + { utc_app_control_get_window_negative2, 1 }, + { utc_app_control_get_window_negative3, 1 }, + { utc_app_control_add_extra_data_positive, 1 }, + { utc_app_control_add_extra_data_negative1, 1 }, + { utc_app_control_add_extra_data_negative2, 1 }, + { utc_app_control_remove_extra_data_positive, 1 }, + { utc_app_control_remove_extra_data_negative1, 1 }, + { utc_app_control_remove_extra_data_negative2, 1 }, + { utc_app_control_remove_extra_data_negative3, 1 }, + { utc_app_control_get_extra_data_positive, 1 }, + { utc_app_control_get_extra_data_negative1, 1 }, + { utc_app_control_get_extra_data_negative2, 1 }, + { utc_app_control_get_extra_data_negative3, 1 }, + { utc_app_control_get_extra_data_negative4, 1 }, + { utc_app_control_foreach_extra_data_positive, 1 }, + { utc_app_control_foreach_extra_data_negative1, 1 }, + { utc_app_control_foreach_extra_data_negative2, 1 }, + { utc_app_control_clone_positive, 1 }, + { utc_app_control_clone_negative1, 1 }, + { utc_app_control_clone_negative2, 1 }, + { utc_app_control_send_launch_request_positive1, 1 }, + { utc_app_control_send_launch_request_positive2, 1 }, + { utc_app_control_send_launch_request_positive3, 1 }, + { utc_app_control_send_launch_request_negative1, 1 }, + { utc_app_control_send_launch_request_negative2, 1 }, + { utc_app_control_reply_to_launch_request_negative1, 1 }, + { utc_app_control_reply_to_launch_request_negative2, 1 }, + { utc_app_control_foreach_app_matched_positive, 1 }, + { utc_app_control_foreach_app_matched_negative1, 1 }, + { utc_app_control_foreach_app_matched_negative2, 1 }, + { utc_app_control_add_extra_data_array_positive, 1 }, + { utc_app_control_add_extra_data_array_negative1, 1 }, + { utc_app_control_add_extra_data_array_negative2, 1 }, + { utc_app_control_add_extra_data_array_negative3, 1 }, + { utc_app_control_get_extra_data_array_positive, 1 }, + { utc_app_control_get_extra_data_array_negative1, 1 }, + { utc_app_control_get_extra_data_array_negative2, 1 }, + { utc_app_control_get_extra_data_array_negative3, 1 }, + { utc_app_control_get_extra_data_array_negative4, 1 }, + { utc_app_control_get_extra_data_array_negative5, 1 }, + { utc_app_control_is_extra_data_array_positive, 1 }, + { utc_app_control_is_extra_data_array_negative1, 1 }, + { utc_app_control_is_extra_data_array_negative2, 1 }, + { utc_app_control_is_extra_data_array_negative3, 1 }, + { utc_app_control_is_extra_data_array_negative4, 1 }, + { utc_app_control_is_reply_requested_positive1, 1 }, + { utc_app_control_is_reply_requested_negative1, 1 }, + { utc_app_control_is_reply_requested_negative2, 1 }, + { utc_app_control_is_reply_requested_negative3, 1 }, + { utc_app_control_get_caller_positive1, 1 }, + { utc_app_control_get_caller_negative1, 1 }, + { utc_app_control_get_caller_negative2, 1 }, + { utc_app_control_get_caller_negative3, 1 }, + { utc_app_control_to_bundle_positive1, 1 }, + { utc_app_control_to_bundle_negative1, 1 }, + { utc_app_control_to_bundle_negative2, 1 }, + { utc_app_control_to_bundle_negative3, 1 }, + { NULL, 0 }, +}; + +static void startup(void) +{ + /* start of TC */ +} + +static void cleanup(void) +{ + /* end of TC */ +} + + +static void utc_app_control_create_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + ret = app_control_create(&app_control); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_create_negative(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_create(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + + +static void utc_app_control_destroy_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_destroy(app_control); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + + +static void utc_app_control_destroy_negative(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_destroy(NULL); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + + +static void utc_app_control_set_operation_positive1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_operation(app_control, input_value); + + dts_message(API_NAME, "ret(%d)", ret); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_set_operation_positive2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_operation(app_control, NULL); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_operation_negative(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_set_operation(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + + + +static void utc_app_control_get_operation_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_operation(app_control, input_value); + + ret = app_control_get_operation(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_get_operation_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_operation(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_operation_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_operation(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_operation_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_operation(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_uri_positive1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_uri(app_control, input_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_set_uri_positive2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_uri(app_control, NULL); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_set_uri_negative(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_get_uri(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_uri_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_uri(app_control, input_value); + + app_control_get_uri(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_get_uri_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_uri(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_get_uri_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_uri(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + +} + +static void utc_app_control_get_uri_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_uri(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); + +} + +static void utc_app_control_set_mime_positive1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_mime(app_control, input_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_mime_positive2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_mime(app_control, NULL); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + + +static void utc_app_control_set_mime_negative(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_set_mime(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_mime_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_mime(app_control, input_value); + + ret = app_control_get_mime(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_mime_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_mime(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_mime_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_mime(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_mime_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_mime(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_package_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_package(app_control, input_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_package_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_set_package(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_set_package_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_set_package(NULL, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_package_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_package(app_control, input_value); + + ret = app_control_get_package(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_package_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_package(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_package_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_package(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_package_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_package(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_app_id_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_app_id(app_control, input_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_app_id_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_set_app_id(NULL, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_set_app_id_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_set_app_id(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_app_id_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_app_id(app_control, input_value); + + ret = app_control_get_app_id(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_app_id_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_app_id(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_app_id_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_app_id(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_app_id_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_app_id(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_category_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_category(app_control, input_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_category_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_set_category(NULL, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_set_category_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + + ret = app_control_set_category(NULL, input_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_category_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + const char *input_value = "INPUT_VALUE"; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_category(app_control, input_value); + + ret = app_control_get_category(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(!strcmp(input_value, output_value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_category_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_category(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE && output_value == NULL) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_category_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *output_value; + + ret = app_control_get_category(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_category_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_category(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_window_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + unsigned int wid = 5; + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_set_window(app_control, wid); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_set_window_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + ret = app_control_set_window(NULL, -1); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_set_window_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + unsigned int wid = 5; + + ret = app_control_set_window(NULL, wid); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_window_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + unsigned int wid = 5; + int output_value = 0; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_set_window(app_control, wid); + + ret = app_control_get_window(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + if(wid == output_value) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_window_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + int output_value = 0; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_window(app_control, &output_value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_window_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + int output_value = 0; + + ret = app_control_get_window(NULL, &output_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_get_window_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_window(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_add_extra_data_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *value = "EXTRA_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_add_extra_data(app_control, key, value); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_add_extra_data_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int passed = 0; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *value = "EXTRA_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + + // key : unll + ret = app_control_add_extra_data(app_control, NULL, value); + + if(ret != SERVICE_ERROR_NONE) + { + passed++; + } + + // key : zero-length + ret = app_control_add_extra_data(app_control, "", value); + + if(ret != SERVICE_ERROR_NONE) + { + passed++; + } + + // value : null + ret = app_control_add_extra_data(app_control, key, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + passed++; + } + + // value : zero-length + ret = app_control_add_extra_data(app_control, key, ""); + + if(ret != SERVICE_ERROR_NONE) + { + passed++; + } + + if(passed == 4) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_add_extra_data_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *value = "EXTRA_VALUE"; + + ret = app_control_add_extra_data(NULL, key, value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_remove_extra_data_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *value = "EXTRA_VALUE"; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_add_extra_data(app_control, key, value); + + ret = app_control_remove_extra_data(app_control, key); + + if(ret == SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_remove_extra_data_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_remove_extra_data(app_control, key); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_remove_extra_data_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + + ret = app_control_remove_extra_data(NULL, key); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } +} + +static void utc_app_control_remove_extra_data_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_remove_extra_data(app_control, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_extra_data_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *value = "EXTRA_VALUE"; + char *ret_value; + + app_control_h app_control; + + app_control_create(&app_control); + + app_control_add_extra_data(app_control, key, value); + + ret = app_control_get_extra_data(app_control, key, &ret_value); + + if(ret == SERVICE_ERROR_NONE && !strcmp(ret_value, value)) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_extra_data_negative1(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *ret_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_extra_data(app_control, key, &ret_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_extra_data_negative2(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + char *ret_value; + + ret = app_control_get_extra_data(NULL, key, &ret_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + +} + +static void utc_app_control_get_extra_data_negative3(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + + char *ret_value; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_extra_data(app_control, NULL, &ret_value); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +static void utc_app_control_get_extra_data_negative4(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + char *key = "EXTRA_KEY"; + + app_control_h app_control; + + app_control_create(&app_control); + + ret = app_control_get_extra_data(app_control, key, NULL); + + if(ret != SERVICE_ERROR_NONE) + { + dts_pass(API_NAME, "passed"); + } + else + { + dts_fail(API_NAME, "failed"); + } + + app_control_destroy(app_control); +} + +#define NUM_EXTRA_DATA 32 + +bool app_control_extra_data(app_control_h app_control, const char *key, void *user_data) +{ + bool *passed = (bool*)user_data; + char *value; + + app_control_get_extra_data(app_control, key, &value); + + if (!strcmp(key, value)) + { + int index = atoi(key); + passed[index] = true; + } + + return true; +} + +static void utc_app_control_foreach_extra_data_positive(void) +{ + const char *API_NAME = __FUNCTION__; + int ret = SERVICE_ERROR_NONE; + int i; + bool passed[NUM_EXTRA_DATA] = {0, }; + int num_passed = 0; + char buf[32] = {0, }; + + app_control_h app_control; + + app_control_create(&app_control); + + for (i=0; i -#include -#include -#include #include -#include #include #include -#include #include -#include +#include #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_ALARM" +#define LOG_TAG "CAPI_APPFW_ALARM" typedef struct { alarm_registered_alarm_cb cb; @@ -87,7 +81,7 @@ static int convert_error_code_to_alarm(const char* function, alarm_error_t alarm LOGE("[%s] INVALID_DATE(0x%08x)", function, ALARM_ERROR_INVALID_DATE); return ALARM_ERROR_INVALID_DATE; break; - + case ERR_ALARM_NO_SERVICE_NAME: LOGE("[%s] INVALID_PARAMETER(0x%08x)", function, ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; @@ -98,74 +92,40 @@ static int convert_error_code_to_alarm(const char* function, alarm_error_t alarm return ALARM_ERROR_CONNECTION_FAIL; break; + case ERR_ALARM_NO_PERMISSION: + LOGE("[%s] PERMISSION_DENIED(0x%08x)", function, ALARM_ERROR_PERMISSION_DENIED); + return ALARM_ERROR_PERMISSION_DENIED; + break; + case ALARMMGR_RESULT_SUCCESS: return ALARM_ERROR_NONE; break; - + default: - return ALARM_ERROR_INVALID_PARAMETER; + return ALARM_ERROR_INVALID_PARAMETER; } - -} - -static int _remove_alarm_cb(alarm_id_t alarm_id, void* user_param) -{ - return alarmmgr_remove_alarm(alarm_id); } int alarm_get_scheduled_date(int alarm_id, struct tm* date) { alarm_error_t result; - alarm_entry_t *entry = NULL; - alarm_date_t adate; + time_t due_time = 0; if (date == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; - } - - entry = alarmmgr_create_alarm(); - - result = alarmmgr_get_info(alarm_id, entry); - if (result != ALARMMGR_RESULT_SUCCESS) - { - if (entry != NULL) { - alarmmgr_free_alarm(entry); - } - return convert_error_code_to_alarm(__FUNCTION__, result); - } - - result = alarmmgr_get_time(entry, &adate); - if (result != ALARMMGR_RESULT_SUCCESS) - { - if (entry != NULL) - { - alarmmgr_free_alarm(entry); - } - return convert_error_code_to_alarm(__FUNCTION__, result); } - - alarm_get_current_time(date); - - date->tm_year = adate.year - 1900; - date->tm_mon = adate.month - 1; - date->tm_mday = adate.day; - date->tm_hour = adate.hour; - date->tm_min = adate.min; - date->tm_sec = adate.sec; - - mktime(date); - - result = alarmmgr_free_alarm(entry); + result = alarmmgr_get_next_duetime(alarm_id, &due_time); if (result != ALARMMGR_RESULT_SUCCESS) { return convert_error_code_to_alarm(__FUNCTION__, result); } - return ALARM_ERROR_NONE; + localtime_r(&due_time, date); + return ALARM_ERROR_NONE; } int alarm_get_scheduled_period(int alarm_id, int* period) @@ -177,10 +137,10 @@ int alarm_get_scheduled_period(int alarm_id, int* period) if (period == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } - + entry = alarmmgr_create_alarm(); result = alarmmgr_get_info(alarm_id, entry); @@ -189,17 +149,17 @@ int alarm_get_scheduled_period(int alarm_id, int* period) if (entry != NULL) { alarmmgr_free_alarm(entry); - } + } return convert_error_code_to_alarm(__FUNCTION__, result); } - + result = alarmmgr_get_repeat_mode(entry, &mode, &value); if (result != ALARMMGR_RESULT_SUCCESS) { if (entry != NULL) { alarmmgr_free_alarm(entry); - } + } return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -209,57 +169,56 @@ int alarm_get_scheduled_period(int alarm_id, int* period) if (entry != NULL) { alarmmgr_free_alarm(entry); - } + } return convert_error_code_to_alarm(__FUNCTION__, result); } - + (*period) = value; return ALARM_ERROR_NONE; - } -int alarm_schedule_after_delay(service_h service, int delay, int period, int *alarm_id) +int alarm_schedule_after_delay(app_control_h app_control, int delay, int period, int *alarm_id) { bundle *bundle_data; int result = 0; - if (service == NULL) + if (app_control == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } - if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE) + if (app_control_to_bundle(app_control, &bundle_data) != APP_CONTROL_ERROR_NONE) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } result = alarmmgr_add_alarm_appsvc(ALARM_TYPE_DEFAULT, delay, period, bundle_data, alarm_id); - + return convert_error_code_to_alarm(__FUNCTION__, result); } -int alarm_schedule_at_date(service_h service, struct tm *date, int period_in_second, int *alarm_id) +int alarm_schedule_at_date(app_control_h app_control, struct tm *date, int period_in_second, int *alarm_id) { alarm_date_t internal_time; alarm_entry_t* alarm_info; bundle *bundle_data; int result; - if (service == NULL || date == NULL) + if (app_control == NULL || date == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } - if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE) + if (app_control_to_bundle(app_control, &bundle_data) != APP_CONTROL_ERROR_NONE) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } - + alarm_info = alarmmgr_create_alarm(); internal_time.year = date->tm_year + 1900; @@ -274,9 +233,9 @@ int alarm_schedule_at_date(service_h service, struct tm *date, int period_in_sec if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } - if (period_in_second > 0) { @@ -289,13 +248,15 @@ int alarm_schedule_at_date(service_h service, struct tm *date, int period_in_sec if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } - + result = alarmmgr_set_type(alarm_info, ALARM_TYPE_DEFAULT); - + if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -303,9 +264,11 @@ int alarm_schedule_at_date(service_h service, struct tm *date, int period_in_sec if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); - } - + } + + alarmmgr_free_alarm(alarm_info); return ALARM_ERROR_NONE; } @@ -320,10 +283,8 @@ int alarm_cancel(int alarm_id) int alarm_cancel_all() { - int result; - - result = alarmmgr_enum_alarm_ids( _remove_alarm_cb, NULL); - + LOGD("%s", __func__); + int result = alarmmgr_remove_all(); return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -334,7 +295,7 @@ int alarm_foreach_registered_alarm(alarm_registered_alarm_cb callback, void* use if (callback == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } @@ -346,7 +307,7 @@ int alarm_foreach_registered_alarm(alarm_registered_alarm_cb callback, void* use }; result = alarmmgr_enum_alarm_ids(alarm_registered_alarm_cb_broker, &foreach_cb_context); - + return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -356,7 +317,7 @@ int alarm_get_current_time(struct tm* date) if (date == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } @@ -366,22 +327,22 @@ int alarm_get_current_time(struct tm* date) } -int alarm_schedule_with_recurrence_week_flag(service_h service, struct tm *date, int week_flag,int *alarm_id) +int alarm_schedule_with_recurrence_week_flag(app_control_h app_control, struct tm *date, int week_flag,int *alarm_id) { alarm_date_t internal_time; alarm_entry_t* alarm_info; bundle *bundle_data; int result; - if (service == NULL || date == NULL) + if (app_control == NULL || date == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } - if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE) + if (app_control_to_bundle(app_control, &bundle_data) != APP_CONTROL_ERROR_NONE) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } @@ -399,6 +360,7 @@ int alarm_schedule_with_recurrence_week_flag(service_h service, struct tm *date, if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -406,21 +368,24 @@ int alarm_schedule_with_recurrence_week_flag(service_h service, struct tm *date, { result = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_WEEKLY, week_flag); } - + if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } - + result = alarmmgr_set_type(alarm_info, ALARM_TYPE_DEFAULT); - + if (result < 0) { + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } result = alarmmgr_add_alarm_appsvc_with_localtime(alarm_info, bundle_data, alarm_id); + alarmmgr_free_alarm(alarm_info); return convert_error_code_to_alarm(__FUNCTION__, result); } @@ -430,10 +395,10 @@ int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag) alarm_entry_t *entry = NULL; alarm_repeat_mode_t mode; int value; - + if(week_flag == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, ALARM_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER); return ALARM_ERROR_INVALID_PARAMETER; } @@ -445,10 +410,10 @@ int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag) if (entry != NULL) { alarmmgr_free_alarm(entry); - } + } return convert_error_code_to_alarm(__FUNCTION__, result); } - + result = alarmmgr_get_repeat_mode(entry, &mode, &value); if(mode != ALARM_REPEAT_MODE_WEEKLY) @@ -459,7 +424,7 @@ int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag) } return ALARM_ERROR_INVALID_PARAMETER; } - + if(result != ALARMMGR_RESULT_SUCCESS) { if (entry != NULL) @@ -475,16 +440,16 @@ int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag) if (entry != NULL) { alarmmgr_free_alarm(entry); - } + } return convert_error_code_to_alarm(__FUNCTION__, result); } - + (*week_flag) = value; - + return ALARM_ERROR_NONE; } -int alarm_get_service(int alarm_id, service_h *service) +int alarm_get_app_control(int alarm_id, app_control_h *app_control) { bundle *b = NULL; int error_code = 0; @@ -500,16 +465,17 @@ int alarm_get_service(int alarm_id, service_h *service) { return ALARM_ERROR_INVALID_PARAMETER; } - - error_code = service_create_request(b, service); - if(error_code != SERVICE_ERROR_NONE) + error_code = app_control_create_request(b, app_control); + + if(error_code != APP_CONTROL_ERROR_NONE) { + bundle_free(b); return ALARM_ERROR_OUT_OF_MEMORY; } bundle_free(b); return ALARM_ERROR_NONE; +} -} \ No newline at end of file diff --git a/app_common/CMakeLists.txt b/app_common/CMakeLists.txt new file mode 100644 index 0000000..25cc14d --- /dev/null +++ b/app_common/CMakeLists.txt @@ -0,0 +1,69 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-appfw-app-common") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR ${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +SET(requires "dlog aul ail capi-base-common") +SET(pc_requires "capi-base-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${requires}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +add_library(${fw_name} SHARED + app_package.c + app_path.c + app_error.c + app_finalizer.c + app_event.c + ) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/appfw + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_requires}) +SET(PC_LDFLAGS -l${fw_name}) + +CONFIGURE_FILE( + ${CMAKE_SOURCE_DIR}/capi-appfw-module.pc.in + ${CMAKE_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + + diff --git a/src/app_error.c b/app_common/app_error.c similarity index 86% rename from src/app_error.c rename to app_common/app_error.c index c7e137c..b32cb51 100755 --- a/src/app_error.c +++ b/app_common/app_error.c @@ -11,24 +11,19 @@ * 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. + * limitations under the License. */ -#include -#include -#include -#include - #include -#include +#include #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_APPLICATION" +#define LOG_TAG "CAPI_APPFW_APPLICATION" static const char* app_error_to_string(app_error_e error) { @@ -61,11 +56,11 @@ int app_error(app_error_e error, const char* function, const char *description) { if (description) { - LOGE("[%s] %s(0x%08x) : %s", function, app_error_to_string(error), error, description); + LOGE("[%s] %s(0x%08x) : %s", function, app_error_to_string(error), error, description); } else { - LOGE("[%s] %s(0x%08x)", function, app_error_to_string(error), error); + LOGE("[%s] %s(0x%08x)", function, app_error_to_string(error), error); } return error; diff --git a/app_common/app_event.c b/app_common/app_event.c new file mode 100644 index 0000000..0cf5de0 --- /dev/null +++ b/app_common/app_event.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +app_device_orientation_e app_convert_appcore_rm(enum appcore_rm rm) +{ + app_device_orientation_e dev_orientation; + + switch (rm) + { + case APPCORE_RM_PORTRAIT_NORMAL: + dev_orientation = APP_DEVICE_ORIENTATION_0; + break; + + case APPCORE_RM_PORTRAIT_REVERSE: + dev_orientation = APP_DEVICE_ORIENTATION_180; + break; + + case APPCORE_RM_LANDSCAPE_NORMAL: + dev_orientation = APP_DEVICE_ORIENTATION_270; + break; + + case APPCORE_RM_LANDSCAPE_REVERSE: + dev_orientation = APP_DEVICE_ORIENTATION_90; + break; + + default: + dev_orientation = APP_DEVICE_ORIENTATION_0; + break; + } + + return dev_orientation; +} + +static int _app_convert_low_memory(void *val) +{ + switch (*(int *)val) { + case VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL: + return APP_EVENT_LOW_MEMORY_NORMAL; + case VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING: + return APP_EVENT_LOW_MEMORY_SOFT_WARNING; + case VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING: + return APP_EVENT_LOW_MEMORY_HARD_WARNING; + default: + return -1; + } +} + +static int _app_convert_low_battery(void *val) +{ + switch (*(int *)val) { + case VCONFKEY_SYSMAN_BAT_POWER_OFF: + return APP_EVENT_LOW_BATTERY_POWER_OFF; + case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW: + return APP_EVENT_LOW_BATTERY_CRITICAL_LOW; + default: + return -1; + } +} + +int app_event_get_low_memory_status(app_event_info_h event_info, app_event_low_memory_status_e *status) +{ + int ret; + + if (event_info == NULL || status == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_info->type != APP_EVENT_LOW_MEMORY) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "event type mismatching"); + + ret = _app_convert_low_memory(event_info->value); + if (ret < 0) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "invalid event info"); + + *status = ret; + + return APP_ERROR_NONE; +} + +int app_event_get_low_battery_status(app_event_info_h event_info, app_event_low_battery_status_e *status) +{ + int ret; + + if (event_info == NULL || status == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_info->type != APP_EVENT_LOW_BATTERY) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "event type mismatching"); + + ret = _app_convert_low_battery(event_info->value); + if (ret < 0) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "invalid event info"); + + *status = ret; + + return APP_ERROR_NONE; +} + +int app_event_get_language(app_event_info_h event_info, char **lang) +{ + if (event_info == NULL || lang == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_info->type != APP_EVENT_LANGUAGE_CHANGED) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "event type mismatching"); + + *lang = strdup(event_info->value); + + return APP_ERROR_NONE; +} + +int app_event_get_region_format(app_event_info_h event_info, char **region) +{ + if (event_info == NULL || region == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_info->type != APP_EVENT_REGION_FORMAT_CHANGED) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "event type mismatching"); + + *region = strdup(event_info->value); + + return APP_ERROR_NONE; +} + +int app_event_get_device_orientation(app_event_info_h event_info, app_device_orientation_e *orientation) +{ + if (event_info == NULL || orientation == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_info->type != APP_EVENT_DEVICE_ORIENTATION_CHANGED) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "event type mismatching"); + + *orientation = app_convert_appcore_rm(*(enum appcore_rm *)(event_info->value)); + + return APP_ERROR_NONE; +} + diff --git a/src/app_finalizer.c b/app_common/app_finalizer.c similarity index 87% rename from src/app_finalizer.c rename to app_common/app_finalizer.c index 264c9f2..cb38346 100755 --- a/src/app_finalizer.c +++ b/app_common/app_finalizer.c @@ -11,15 +11,12 @@ * 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. + * limitations under the License. */ -#include #include -#include -#include -#include +#include typedef struct _app_finalizer_s_ { app_finalizer_cb callback; @@ -55,7 +52,7 @@ int app_finalizer_add(app_finalizer_cb callback, void *data) { finalizer_tail = finalizer_tail->next; } - + finalizer_tail->next = finalizer_new; return APP_ERROR_NONE; @@ -76,7 +73,7 @@ int app_finalizer_remove(app_finalizer_cb callback) } finalizer_node = finalizer_node->next; - } + } return APP_ERROR_INVALID_PARAMETER; } @@ -87,13 +84,16 @@ void app_finalizer_execute(void) app_finalizer_h finalizer_executed; app_finalizer_cb finalizer_cb = NULL; - while (finalizer_node->next) + if(finalizer_node) + finalizer_node = finalizer_node->next; + + while (finalizer_node) { - finalizer_cb = finalizer_node->next->callback; + finalizer_cb = finalizer_node->callback; - finalizer_cb(finalizer_node->next->data); + finalizer_cb(finalizer_node->data); - finalizer_executed = finalizer_node->next; + finalizer_executed = finalizer_node; finalizer_node = finalizer_node->next; diff --git a/src/app_package.c b/app_common/app_package.c similarity index 81% rename from src/app_package.c rename to app_common/app_package.c index a151744..e4e7b32 100755 --- a/src/app_package.c +++ b/app_common/app_package.c @@ -11,44 +11,36 @@ * 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. + * limitations under the License. */ -#include #include #include #include -#include -#include -#include -#include -#include #include #include -#include -#include -#include +#include #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_APPLICATION" +#define LOG_TAG "CAPI_APPFW_APPLICATION" -int app_get_package_app_name(const char *package, char **name) +int app_get_package_app_name(const char *appid, char **name) { char *name_token = NULL; - if (package == NULL) + if (appid == NULL) { return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); } // com.vendor.name -> name - name_token = strrchr(package, '.'); + name_token = strrchr(appid, '.'); if (name_token == NULL) { @@ -75,6 +67,7 @@ int app_get_package(char **package) int app_get_id(char **id) { static char id_buf[TIZEN_PATH_MAX] = {0, }; + int ret = -1; if (id == NULL) { @@ -83,7 +76,10 @@ int app_get_id(char **id) if (id_buf[0] == '\0') { - aul_app_get_pkgname_bypid(getpid(), id_buf, sizeof(id_buf)); + ret = aul_app_get_appid_bypid(getpid(), id_buf, sizeof(id_buf)); + if (ret < 0) { + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the application ID"); + } } if (id_buf[0] == '\0') @@ -107,20 +103,20 @@ static int app_get_appinfo(const char *package, const char *property, char **val char *appinfo_value; char *appinfo_value_dup; - if (ail_package_get_appinfo(package, &appinfo) != 0) + if (ail_get_appinfo(package, &appinfo) != 0) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get app-info"); } - + if (ail_appinfo_get_str(appinfo, property, &appinfo_value) != 0) { - ail_package_destroy_appinfo(appinfo); + ail_destroy_appinfo(appinfo); return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get app-property"); } appinfo_value_dup = strdup(appinfo_value); - ail_package_destroy_appinfo(appinfo); + ail_destroy_appinfo(appinfo); if (appinfo_value_dup == NULL) { @@ -128,7 +124,7 @@ static int app_get_appinfo(const char *package, const char *property, char **val } *value = appinfo_value_dup; - + return APP_ERROR_NONE; } @@ -142,7 +138,7 @@ int app_get_name(char **name) return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); } - if (app_get_package(&package) != 0) + if (app_get_id(&package) != 0) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); } @@ -167,7 +163,7 @@ int app_get_version(char **version) return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); } - if (app_get_package(&package) != 0) + if (app_get_id(&package) != 0) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); } @@ -179,6 +175,6 @@ int app_get_version(char **version) free(package); } - return retval; + return retval; } diff --git a/app_common/app_path.c b/app_common/app_path.c new file mode 100755 index 0000000..e534130 --- /dev/null +++ b/app_common/app_path.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +char *app_get_data_path(void) +{ + const char *buf = aul_get_app_data_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_cache_path(void) +{ + const char *buf = aul_get_app_cache_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_resource_path(void) +{ + const char *buf = aul_get_app_resource_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_shared_data_path(void) +{ + const char *buf = aul_get_app_shared_data_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_shared_resource_path(void) +{ + const char *buf = aul_get_app_shared_resource_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_shared_trusted_path(void) +{ + const char *buf = aul_get_app_shared_trusted_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_external_data_path(void) +{ + const char *buf = aul_get_app_external_data_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_external_cache_path(void) +{ + const char *buf = aul_get_app_external_cache_path(); + return buf != NULL ? strdup(buf) : NULL; +} + +char *app_get_external_shared_data_path(void) +{ + const char *buf = aul_get_app_external_shared_data_path(); + return buf != NULL ? strdup(buf) : NULL; +} diff --git a/app_control/CMakeLists.txt b/app_control/CMakeLists.txt new file mode 100644 index 0000000..6350997 --- /dev/null +++ b/app_control/CMakeLists.txt @@ -0,0 +1,65 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-appfw-app-control") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR ${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +SET(requires "dlog bundle aul appsvc capi-base-common capi-security-privilege-manager pkgmgr-info") +SET(pc_requires "capi-base-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${requires}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +add_library(${fw_name} SHARED + app_control.c + ) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/appfw + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_requires}) +SET(PC_LDFLAGS -l${fw_name}) + +CONFIGURE_FILE( + ${CMAKE_SOURCE_DIR}/capi-appfw-module.pc.in + ${CMAKE_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + + diff --git a/app_control/app_control.c b/app_control/app_control.c new file mode 100755 index 0000000..0ac2825 --- /dev/null +++ b/app_control/app_control.c @@ -0,0 +1,1397 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "CAPI_APPFW_APP_CONTROL" + +#ifndef TIZEN_PATH_MAX +#define TIZEN_PATH_MAX 1024 +#endif + +#define BUNDLE_KEY_PREFIX_AUL "__AUL_" +#define BUNDLE_KEY_PREFIX_SERVICE "__APP_SVC_" + +#define BUNDLE_KEY_OPERATION "__APP_SVC_OP_TYPE__" +#define BUNDLE_KEY_URI "__APP_SVC_URI__" +#define BUNDLE_KEY_MIME "__APP_SVC_MIME_TYPE__" +#define BUNDLE_KEY_DATA "__APP_SVC_DATA__" +#define BUNDLE_KEY_PACKAGE "__APP_SVC_PKG_NAME__" +#define BUNDLE_KEY_WINDOW "__APP_SVC_K_WIN_ID__" +#define BUNDLE_KEY_CATEGORY "__APP_SVC_CATEGORY__" + +typedef enum { + APP_CONTROL_TYPE_REQUEST, + APP_CONTROL_TYPE_EVENT, + APP_CONTROL_TYPE_REPLY, +} app_control_type_e; + +struct app_control_s { + int id; + app_control_type_e type; + bundle *data; + int launch_pid; +}; + +typedef struct app_control_request_context_s { + app_control_h app_control; + app_control_reply_cb reply_cb; + void *user_data; +} *app_control_request_context_h; + +extern int appsvc_allow_transient_app(bundle *b, unsigned int id); +extern int appsvc_request_transient_app(bundle *b, unsigned int callee_id, appsvc_host_res_fn cbfunc, void *data); + +static int app_control_create_reply(bundle *data, struct app_control_s **app_control); + +static const char* app_control_error_to_string(app_control_error_e error) +{ + switch (error) + { + case APP_CONTROL_ERROR_NONE: + return "NONE"; + + case APP_CONTROL_ERROR_INVALID_PARAMETER: + return "INVALID_PARAMETER"; + + case APP_CONTROL_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + + case APP_CONTROL_ERROR_APP_NOT_FOUND: + return "APP_NOT_FOUND"; + + case APP_CONTROL_ERROR_KEY_NOT_FOUND: + return "KEY_NOT_FOUND"; + + case APP_CONTROL_ERROR_KEY_REJECTED: + return "KEY_REJECTED"; + + case APP_CONTROL_ERROR_INVALID_DATA_TYPE: + return "INVALID_DATA_TYPE"; + + case APP_CONTROL_ERROR_LAUNCH_REJECTED: + return "LAUNCH_REJECTED"; + + case APP_CONTROL_ERROR_PERMISSION_DENIED: + return "PERMISSION_DENIED"; + + case APP_CONTROL_ERROR_LAUNCH_FAILED: + return "LAUNCH_FAILED"; + + case APP_CONTROL_ERROR_TIMED_OUT: + return "TIMED_OUT"; + + default : + return "UNKNOWN"; + } +} + +int app_control_error(app_control_error_e error, const char* function, const char *description) +{ + if (description) + { + LOGE("[%s] %s(0x%08x) : %s", function, app_control_error_to_string(error), error, description); + } + else + { + if(error == APP_CONTROL_ERROR_KEY_NOT_FOUND) + LOGW("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error); + else + LOGE("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error); + } + + return error; +} + +static int app_control_validate_extra_data(const char *data) +{ + if (data == NULL || data[0] == '\0') + { + return APP_CONTROL_ERROR_INVALID_PARAMETER; + } + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_validate(app_control_h app_control) +{ + if (app_control == NULL || app_control->data == NULL) + { + return APP_CONTROL_ERROR_INVALID_PARAMETER; + } + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_new_id() +{ + static int sid = 0; + return sid++; +} + +int app_control_validate_internal_key(const char *key) +{ + if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0) + { + return -1; + } + + if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0) + { + return -1; + } + + return 0; +} + +static void app_control_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data) +{ + app_control_request_context_h request_context; + app_control_h request; + app_control_h reply = NULL; + app_control_result_e result; + void *user_data; + app_control_reply_cb reply_cb; + + if (appsvc_data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control reply"); + return; + } + + if (app_control_create_reply(appsvc_bundle, &reply) != 0) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control reply"); + return; + } + + request_context = appsvc_data; + request = request_context->app_control; + + switch (appsvc_result) + { + case APPSVC_RES_OK: + result = APP_CONTROL_RESULT_SUCCEEDED; + break; + + case APPSVC_RES_NOT_OK: + result = APP_CONTROL_RESULT_FAILED; + break; + + case APPSVC_RES_CANCEL: + result = APP_CONTROL_RESULT_CANCELED; + break; + + default: + result = APP_CONTROL_RESULT_CANCELED; + break; + } + + user_data = request_context->user_data; + reply_cb = request_context->reply_cb; + + if (reply_cb != NULL) + { + reply_cb(request, reply, result, user_data); + } + else + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback "); + } + + app_control_destroy(reply); + + if (request_context->app_control != NULL) + { + app_control_destroy(request_context->app_control); + } + + free(request_context); +} + +int app_control_create_request(bundle *data, app_control_h *app_control) +{ + struct app_control_s *app_control_request; + + if (app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_request = malloc(sizeof(struct app_control_s)); + + if (app_control_request == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_request->type = APP_CONTROL_TYPE_REQUEST; + + if (data != NULL) + { + app_control_request->data = bundle_dup(data); + } + else + { + app_control_request->data = bundle_create(); + } + + if (app_control_request->data == NULL) + { + free(app_control_request); + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle"); + } + + app_control_request->id = app_control_new_id(); + app_control_request->launch_pid = -1; + + *app_control = app_control_request; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_create(app_control_h *app_control) +{ + return app_control_create_request(NULL, app_control); +} + +int app_control_create_event(bundle *data, struct app_control_s **app_control) +{ + struct app_control_s *app_control_event; + + const char *operation; + + if (data == NULL || app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_event = malloc(sizeof(struct app_control_s)); + + if (app_control_event == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_event->type = APP_CONTROL_TYPE_EVENT; + app_control_event->data = bundle_dup(data); + app_control_event->id = app_control_new_id(); + + operation = appsvc_get_operation(app_control_event->data); + + if (operation == NULL) + { + appsvc_set_operation(app_control_event->data, APP_CONTROL_OPERATION_DEFAULT); + } + + *app_control = app_control_event; + + return APP_CONTROL_ERROR_NONE; +} + +static int app_control_create_reply(bundle *data, struct app_control_s **app_control) +{ + struct app_control_s *app_control_reply; + + if (data == NULL || app_control == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_reply = malloc(sizeof(struct app_control_s)); + + if (app_control_reply == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_reply->type = APP_CONTROL_TYPE_REPLY; + app_control_reply->data = bundle_dup(data); + app_control_reply->id = app_control_new_id(); + + *app_control = app_control_reply; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_destroy(app_control_h app_control) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if(app_control->type == APP_CONTROL_TYPE_REQUEST && app_control->launch_pid > 0) + { + aul_remove_caller_cb(app_control->launch_pid); + } + + bundle_free(app_control->data); + app_control->data = NULL; + free(app_control); + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_to_bundle(app_control_h app_control, bundle **data) +{ + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + *data = app_control->data; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_set_operation(app_control_h app_control, const char *operation) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (operation != NULL) + { + if (appsvc_set_operation(app_control->data, operation) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_OPERATION); + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_get_operation(app_control_h app_control, char **operation) +{ + const char *operation_value; + + if (app_control_validate(app_control) || operation == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + operation_value = appsvc_get_operation(app_control->data); + + if (operation_value != NULL) + { + *operation = strdup(operation_value); + } + else + { + *operation = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_uri(app_control_h app_control, const char *uri) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (uri != NULL) + { + if (appsvc_set_uri(app_control->data, uri) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_URI); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_uri(app_control_h app_control, char **uri) +{ + const char *uri_value; + + if (app_control_validate(app_control) || uri == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + uri_value = appsvc_get_uri(app_control->data); + + if (uri_value != NULL) + { + *uri = strdup(uri_value); + } + else + { + *uri = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_mime(app_control_h app_control, const char *mime) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (mime != NULL) + { + if (appsvc_set_mime(app_control->data, mime) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_MIME); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_mime(app_control_h app_control, char **mime) +{ + const char *mime_value; + + if (app_control_validate(app_control) || mime == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + mime_value = appsvc_get_mime(app_control->data); + + if (mime_value != NULL) + { + *mime = strdup(mime_value); + } + else + { + *mime = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_category(app_control_h app_control, const char *category) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (category != NULL) + { + if (appsvc_set_category(app_control->data, category) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_CATEGORY); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_category(app_control_h app_control, char **category) +{ + const char *category_value; + + if (app_control_validate(app_control) || category == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + category_value = appsvc_get_category(app_control->data); + + if (category_value != NULL) + { + *category = strdup(category_value); + } + else + { + *category = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_set_package(app_control_h app_control, const char *package) +{ + // TODO: this function must be deprecated + return app_control_set_app_id(app_control, package); +} + +int app_control_get_package(app_control_h app_control, char **package) +{ + // TODO: this function must be deprecated + return app_control_get_app_id(app_control, package); +} + + +int app_control_set_app_id(app_control_h app_control, const char *app_id) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_id != NULL) + { + if (appsvc_set_appid(app_control->data, app_id) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_PACKAGE); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_app_id(app_control_h app_control, char **app_id) +{ + const char *app_id_value; + + if (app_control_validate(app_control) || app_id == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_id_value = appsvc_get_appid(app_control->data); + + if (app_id_value != NULL) + { + *app_id = strdup(app_id_value); + } + else + { + *app_id = NULL; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_set_window(app_control_h app_control, unsigned int id) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (id > 0) + { + if (appsvc_allow_transient_app(app_control->data, id) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id"); + } + } + else + { + bundle_del(app_control->data, BUNDLE_KEY_WINDOW); + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_get_window(app_control_h app_control, unsigned int *id) +{ + const char *window_id; + + if (app_control_validate(app_control) || id == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW); + + if (window_id != NULL) + { + *id = atoi(window_id); + } + else + { + *id = 0; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_clone(app_control_h *clone, app_control_h app_control) +{ + app_control_h app_control_clone; + + if (app_control_validate(app_control) || clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + app_control_clone = malloc(sizeof(struct app_control_s)); + + if (app_control_clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle"); + } + + app_control_clone->id = app_control_new_id(); + app_control_clone->type = app_control->type; + app_control_clone->data = bundle_dup(app_control->data); + + *clone = app_control_clone; + + return APP_CONTROL_ERROR_NONE; +} + +static void update_launch_pid(int launched_pid, void *data) +{ + app_control_h app_control; + + if(data == NULL) + return; + + app_control = data; + + app_control->launch_pid = launched_pid; +} + +int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data) +{ + const char *operation; + + bool implicit_default_operation = false; + int launch_pid; + + app_control_request_context_h request_context = NULL; + + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + operation = appsvc_get_operation(app_control->data); + if (operation == NULL) + { + implicit_default_operation = true; + operation = APP_CONTROL_OPERATION_DEFAULT; + } + + // Check the privilege for call operation + if (!strcmp(operation, APP_CONTROL_OPERATION_CALL)) + { + int ret; + char app_id[256]; + char *pkg_id; + pkgmgrinfo_appinfo_h app_info; + + ret = aul_app_get_appid_bypid(getpid(), app_id, sizeof(app_id)); + if (ret != AUL_R_OK) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to get the app_id of the current application"); + } + + ret = pkgmgrinfo_appinfo_get_appinfo(app_id, &app_info); + if (ret != PMINFO_R_OK) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to get app_info of the current application"); + } + + ret = pkgmgrinfo_appinfo_get_pkgname(app_info, &pkg_id); + if (ret != PMINFO_R_OK) + { + pkgmgrinfo_appinfo_destroy_appinfo(app_info); + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "Failed to get pkg_id of the current application"); + } + + ret = privilege_checker_check_package_privilege(pkg_id, "http://tizen.org/privilege/call"); + pkgmgrinfo_appinfo_destroy_appinfo(app_info); + if (ret != PRIV_CHECKER_ERR_NONE) + { + if (ret == PRIV_CHECKER_ERR_INVALID_PRIVILEGE) + { + return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, "no privilege for Call operation"); + } + else + { + return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL); + } + } + } + + // operation : default + if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) + { + const char *appid = appsvc_get_appid(app_control->data); + if (appid == NULL) + { + return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value"); + } + } + + if (callback != NULL) + { + app_control_h request_clone = NULL; + + request_context = calloc(1, sizeof(struct app_control_request_context_s)); + + if (request_context == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + request_context->reply_cb = callback; + + if (app_control_clone(&request_clone, app_control) != APP_CONTROL_ERROR_NONE) + { + free(request_context); + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the app_control request handle"); + } + + request_context->app_control = request_clone; + request_context->user_data = user_data; + } + + if (implicit_default_operation == true) + { + appsvc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT); + } + + launch_pid = appsvc_run_service(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context); + + if (implicit_default_operation == true) + { + bundle_del(app_control->data, BUNDLE_KEY_OPERATION); + } + + if (launch_pid < 0) + { + if (launch_pid == APPSVC_RET_ENOMATCH) + { + return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL); + } + else if (launch_pid == APPSVC_RET_EILLACC) + { + return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); + } + else if (launch_pid == APPSVC_RET_EINVAL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL); + } + } + + app_control->launch_pid = launch_pid; + + aul_add_caller_cb(launch_pid, update_launch_pid, app_control); + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_send_terminate_request(app_control_h app_control) +{ + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if(app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + appsvc_subapp_terminate_request_pid(app_control->launch_pid); + + return APP_CONTROL_ERROR_NONE; +} + +static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data) +{ + bundle *reply_data = user_data; + char *value = NULL; + char **value_array = NULL; + int value_array_length = 0; + int value_array_index = 0; + + if (reply_data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return false; + } + + if (appsvc_data_is_array(app_control->data, key)) + { + app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length); + appsvc_add_data_array(reply_data, key, (const char**)value_array, value_array_length); + + for (value_array_index=0; value_array_index < value_array_length; value_array_index++) + { + free(value_array[value_array_index]); + } + + free(value_array); + } + else + { + app_control_get_extra_data(app_control, key, &value); + appsvc_add_data(reply_data, key, value); + free(value); + } + + return true; +} + +int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result) +{ + bundle *reply_data; + int appsvc_result; + int ret = 0; + + if (app_control_validate(reply) || app_control_validate(request)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (appsvc_create_result_bundle(request->data, &reply_data) != 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle"); + } + + app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data); + + switch (result) + { + case APP_CONTROL_RESULT_SUCCEEDED: + appsvc_result = APPSVC_RES_OK; + break; + + case APP_CONTROL_RESULT_FAILED: + appsvc_result = APPSVC_RES_NOT_OK; + break; + + case APP_CONTROL_RESULT_CANCELED: + appsvc_result = APPSVC_RES_CANCEL; + break; + + default: + appsvc_result = APPSVC_RES_CANCEL; + break; + } + + ret = appsvc_send_result(reply_data, appsvc_result); + if (ret < 0) + { + if (ret == APPSVC_RET_EINVAL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL); + } + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (appsvc_get_data(app_control->data, key) != NULL) + { + // overwrite any existing value + bundle_del(app_control->data, key); + } + + if (appsvc_add_data(app_control->data, key, value) != 0) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle"); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (value == NULL || length <= 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array"); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (appsvc_get_data_array(app_control->data, key, NULL) != NULL) + { + // overwrite any existing value + bundle_del(app_control->data,key); + } + + if (appsvc_add_data_array(app_control->data, key, value, length) != 0) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle"); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_remove_extra_data(app_control_h app_control, const char *key) +{ + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + if (bundle_del(app_control->data, key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_extra_data(app_control_h app_control, const char *key, char **value) +{ + const char *data_value; + + if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + data_value = appsvc_get_data(app_control->data, key); + + if (data_value == NULL) + { + if (errno == ENOTSUP) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + } + + *value = strdup(data_value); + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length) +{ + const char **array_data; + int array_data_length; + char **array_data_clone; + int i; + + if (app_control_validate(app_control) || app_control_validate_extra_data(key)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (value == NULL || length == 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control_validate_internal_key(key)) + { + return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); + } + + array_data = appsvc_get_data_array(app_control->data, key, &array_data_length); + + if (array_data == NULL) + { + if (errno == ENOTSUP) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); + } + else + { + return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); + } + } + + array_data_clone = calloc(array_data_length, sizeof(char*)); + + if (array_data_clone == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + for (i=0; idata, key)) + { + *array = false; + } + else + { + *array = true; + } + + return APP_CONTROL_ERROR_NONE; +} + + +typedef struct { + app_control_h app_control; + app_control_extra_data_cb callback; + void* user_data; + bool foreach_break; +} foreach_context_extra_data_t; + +static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data) +{ + foreach_context_extra_data_t* foreach_context = NULL; + app_control_extra_data_cb extra_data_cb; + + if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY)) + { + return; + } + + foreach_context = (foreach_context_extra_data_t*)user_data; + + if (foreach_context->foreach_break == true) + { + return; + } + + if (app_control_validate_internal_key(key)) + { + return; + } + + extra_data_cb = foreach_context->callback; + + if (extra_data_cb != NULL) + { + bool stop_foreach = false; + + stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data); + + foreach_context->foreach_break = stop_foreach; + } + +} + + +int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data) +{ + foreach_context_extra_data_t foreach_context = { + .app_control = app_control, + .callback = callback, + .user_data = user_data, + .foreach_break = false + }; + + if (app_control_validate(app_control) || callback == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context); + + return APP_CONTROL_ERROR_NONE; +} + +typedef struct { + app_control_h app_control; + app_control_app_matched_cb callback; + void* user_data; + bool foreach_break; +} foreach_context_launchable_app_t; + +int app_control_cb_broker_foreach_app_matched(const char *package, void *data) +{ + foreach_context_launchable_app_t *foreach_context; + app_control_app_matched_cb app_matched_cb; + + if (package == NULL || data == NULL) + { + app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return -1; + } + + foreach_context = (foreach_context_launchable_app_t*)data; + + if (foreach_context->foreach_break == true) + { + return -1; + } + + app_matched_cb = foreach_context->callback; + + if (app_matched_cb != NULL) + { + bool stop_foreach = false; + + stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data); + + foreach_context->foreach_break = stop_foreach; + } + + return 0; +} + +int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data) +{ + foreach_context_launchable_app_t foreach_context = { + .app_control = app_control, + .callback = callback, + .user_data = user_data, + .foreach_break = false + }; + + if (app_control_validate(app_control) || callback == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + appsvc_get_list(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context); + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_get_caller(app_control_h app_control, char **package) +{ + const char *bundle_value; + char *package_dup; + + if (app_control_validate(app_control) || package == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control->type != APP_CONTROL_TYPE_EVENT) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type"); + } + + bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID); + if (bundle_value == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller"); + } + + package_dup = strdup(bundle_value); + + if (package_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + *package = package_dup; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_is_reply_requested(app_control_h app_control, bool *requested) +{ + const char *bundle_value; + + if (app_control_validate(app_control) || requested == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (app_control->type != APP_CONTROL_TYPE_EVENT) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type"); + } + + bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT); + + if (bundle_value != NULL) + { + *requested = true; + } + else + { + *requested = false; + } + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_import_from_bundle(app_control_h app_control, bundle *data) +{ + bundle *data_dup = NULL; + + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + data_dup = bundle_dup(data); + + if (data_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); + } + + if (app_control->data != NULL) + { + bundle_free(app_control->data); + } + + app_control->data = data_dup; + + return APP_CONTROL_ERROR_NONE; +} + +int app_control_export_as_bundle(app_control_h app_control, bundle **data) +{ + bundle *data_dup = NULL; + + if (app_control_validate(app_control) || data == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + data_dup = bundle_dup(app_control->data); + + if (data_dup == NULL) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); + } + + *data = data_dup; + + return APP_CONTROL_ERROR_NONE; +} + + +int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data) +{ + int ret; + + if (app_control_validate(app_control)) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + ret = appsvc_request_transient_app(app_control->data, callee_id, (appsvc_host_res_fn)cbfunc, data); + + if (ret < 0) + { + return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + return APP_CONTROL_ERROR_NONE; +} + diff --git a/capi-appfw-application.manifest b/capi-appfw-application.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/capi-appfw-application.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/capi-appfw-application.pc.in b/capi-appfw-module.pc.in similarity index 90% rename from capi-appfw-application.pc.in rename to capi-appfw-module.pc.in index f0c4fb4..c1a82ff 100755 --- a/capi-appfw-application.pc.in +++ b/capi-appfw-module.pc.in @@ -9,7 +9,7 @@ includedir=/usr/include/appfw Name: @PC_NAME@ Description: @PACKAGE_DESCRIPTION@ Version: @VERSION@ -Requires: @PC_REQUIRED@ +Requires: @PC_REQUIRED@ Libs: -L${libdir} @PC_LDFLAGS@ Cflags: -I${includedir} diff --git a/debian/control b/debian/control index 264486a..031e7c0 100755 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Source: capi-appfw-application Section: libs Priority: extra Maintainer: Woongsuk Cho , junghyuk park -Build-Depends: debhelper (>= 5), dlog-dev, libbundle-dev, libappcore-common-dev, libappcore-efl-dev, libaul-1-dev, libail-0-dev, libappsvc-dev, libnotification-dev, libelm-dev, capi-base-common-dev, libalarm-dev, libsqlite3-dev +Build-Depends: debhelper (>= 5), dlog-dev, libbundle-dev, libappcore-common-dev, libappcore-efl-dev, libaul-1-dev, libail-0-dev, libappsvc-dev, lbelm-dev, capi-base-common-dev, libalarm-dev, libsqlite3-dev Package: capi-appfw-application Architecture: any diff --git a/doc/appfw_alarm_doc.h b/doc/appfw_alarm_doc.h new file mode 100755 index 0000000..8ef2681 --- /dev/null +++ b/doc/appfw_alarm_doc.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_ALARM_DOC_H__ +#define __TIZEN_APPFW_ALARM_DOC_H__ + + /** + * @ingroup CAPI_APPLICATION_MODULE + * @defgroup CAPI_ALARM_MODULE Alarm + * @brief The @ref CAPI_ALARM_MODULE API allows setting an "alarm clock" for the delivery of a notification at some point in the future. + * + * @section CAPI_ALARM_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_ALARM_MODULE_OVERVIEW Overview + * Mobile devices typically give constant access to information from various sources. Some of this information is best delivered + * through alarms - the most obvious case is a calendar scheduling application which lets you know when a meeting is about to start. + * Alarms are certainly better than actively waiting in a loop. They are also better than putting an interface to sleep because they do not + * block your main UI thread. Use of alarms helps build smooth user experiences and implements unattended data synchronization tasks. + * If an application is installed after setting the alarm, your alarm is cancelled automatically.\n + * When the alarm is expired, Alarm Manager will turn on LCD to prohibit background jobs. + * Please make sure background jobs using alarm APIs are not allowed. + * + * There are 3 ways to set an alarm. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FUNCTIONDESCRIPTION
alarm_schedule_once_after_delay()Sets an alarm to be triggered at specific time once
alarm_schedule_once_at_date()Sets an alarm to be triggered after specific delay once
alarm_schedule_with_recurrence_week_flag()Sets an alarm to be triggered at specific time with recurrent days of the week(can repeat on days of the week)
+ * \n + * + */ + +#endif /* __TIZEN_APPFW_ALARM_DOC_H__ */ diff --git a/doc/appfw_app_common_doc.h b/doc/appfw_app_common_doc.h new file mode 100755 index 0000000..d91cd20 --- /dev/null +++ b/doc/appfw_app_common_doc.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014 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 __TIZEN_APPFW_APP_COMMON_DOC_H__ +#define __TIZEN_APPFW_APP_COMMON_DOC_H__ + + /** + * @ingroup CAPI_APPLICATION_MODULE + * @defgroup CAPI_APP_COMMON_MODULE App Common + * @brief The @ref CAPI_APP_COMMON_MODULE API provides functions to getting information about the application. + * + * @addtogroup CAPI_APP_COMMON_MODULE + * + * @section CAPI_APP_COMMON_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_APP_COMMON_MODULE_OVERVIEW Overview + * + * The App common API provides common apis that can be used at UI application and Service application. + * This API provides interfaces for getting information about the application. + * + * @subsection CAPI_APPLICATION_MODULE_PACKAGE Application Package + * The Tizen native application consists of structured directories to manage the application executable file, library files, resource files, and data. + * When you build the application, the Tizen SDK packages those as an application package for distribution. + * + * @image html capi_appfw_application_package.png "Application package" + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
DirectoriesDescription
<package id>The fully qualified name of an application (such as org.tizen.calculator).
binThe executable file of the application.
libThe application library files
resThe root directory in which all resource files are located.\n + * The application cannot write and modify any resource files
dataThe root directory in which an application's private data is located.\n + * The application can read and write its own data files in the application's data directory.
shared/The shared directory for sharing with other applications.
+ * + * @subsection CAPI_APPLICATION_MODULE_GET_INFORMATION Getting Information About the Application + * The API provides functions for obtaining an application's package name and absolute path to specified resources + * like Image, Sound, Video, UI layout (EDJ), and so on. + * It also provides functions to : + * - Get the current orientation of the device + * - Get the Internal/External root folders which are shared among all applications + * + */ + +#endif /* __TIZEN_APPFW_APP_COMMON_DOC_H__ */ diff --git a/doc/appfw_app_control_doc.h b/doc/appfw_app_control_doc.h new file mode 100755 index 0000000..1187ac8 --- /dev/null +++ b/doc/appfw_app_control_doc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_APP_CONTROL_DOC_H__ +#define __TIZEN_APPFW_APP_CONTROL_DOC_H__ + + /** + * @ingroup CAPI_APPLICATION_MODULE + * @defgroup CAPI_APP_CONTROL_MODULE App Control + * @brief The @ref CAPI_APP_CONTROL_MODULE API provides functions to launch other applications. + * + * @section CAPI_APP_CONTROL_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_APP_CONTROLMODULE_OVERVIEW Overview + * Platform Application Controls + */ + +#endif /* __TIZEN_APPFW_APP_CONTROL_DOC_H__ */ diff --git a/doc/appfw_app_doc.h b/doc/appfw_app_doc.h new file mode 100755 index 0000000..c65eadb --- /dev/null +++ b/doc/appfw_app_doc.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_APP_DOC_H__ +#define __TIZEN_APPFW_APP_DOC_H__ + +/** +* @ingroup CAPI_APPLICATION_FRAMEWORK +* @defgroup CAPI_APPLICATION_MODULE Application +* +* @addtogroup CAPI_APPLICATION_MODULE +* +* @brief The @ref CAPI_APPLICATION_MODULE API provides functions to manage the main event loop, the application's state change events, basic system events, +* and get information about the application. +* +* +* @section CAPI_APPLICATION_MODULE_HEADER Required Header +* \#include +* +* @section CAPI_APPLICATION_MODULE_OVERVIEW Overview +* +* The Application API handles an application state change or system events and provides mechanisms that launch other applications. +* +* The Tizen native application is similar to a conventional Linux application, but has some additional features optimized for mobile +* devices, which may have constraints such as relatively small screen sizes and lack of system resources compared to a larger system. +* For example, for power management reasons, the application may wish to take actions to reduce usage when it finds out that it had its display window +* covered over by another application's window. State change events are delivered so that this is possible. +* +* The Application API provides interfaces for the following three categories: +* - Starting or exiting the main event loop (mandatory for every Tizen native application) +* - Registering callbacks for application state change events +* - Registering callbacks for basic system events +* +* @subsection CAPI_APPLICATION_MODULE_EVENT_LOOP Event Loop +* For an application to operate successfully, it must receive events from the platform. +* For this, it needs to start the main event loop - this is mandatory for all Tizen native applications. +* The ui_app_main() function is used to start the event loop. +* Before calling this function, you should set up the #ui_app_lifecycle_callback_s structure which is passed to the function (see the following sections). +* +* @subsection CAPI_APPLICATION_MODULE_STATE_CHANGE_EVENT Registering Callbacks for Application State Change Events +* The application state change events include the following: +*

+* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
State Description
app_create_cb() Hook to take necessary actions before the main event loop starts. +* Your UI generation code should be placed here so that you do not miss any events from your application UI. +*
app_pause_cb() Hook to take necessary actions when an application becomes invisible. +* For example, you might wish to release memory resources so other applications can use these resources. +* It is important not to starve the application in front, which is interacting with the user. +*
app_resume_cb() Hook to take necessary actions when an application becomes visible. +* If anything is relinquished in app_pause_cb() but is necessary to resume +* the application, it must be re-allocated here. +*
app_terminate_cb() Hook to take necessary actions when your application is terminating. +* Your application should release all resources, especially any +* allocations and shared resources must be freed here so other running applications can fully use these shared resources. +*
app_control_cb() Hook to take necessary actions when your application called by another application. +* When the application gets launch request, this callback function is called. +* The application can get information about what is to be performed by using App Control API from app_control handle. +*
+* +* For further explanation of application state changes, see the @ref CAPI_APPLICATION_MODULE_STATES_TRANSITIONS section. +* +* @subsection CAPI_APPLICATION_MODULE_SYSTEM_EVENT Registering Callbacks for System Events +* The system event callbacks can be registered using ui_app_add_event_handler(). Multiple system event callbacks can be registered. +* The basic system event includes the following: +*

+* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
System event types Description
APP_EVENT_LOW_MEMORY The system memory is running low. +* Recommended actions are as follows: +* - Action 1. Save data in main memory to persistent memory/storage +* to avoid data loss in case the Tizen platform Low Memory Killer kills your application to get more free memory. +* The explanation of how Low Memory Killer behaves is here(link), but basically if the low memory notice does not lead to enough +* memory being freed, something will be killed. Release cached data in main memory to secure more free memory. +*
APP_EVENT_LOW_BATTERY The battery power is running low. +* Recommended actions are as follows: +* - Action 1. Save data in main memory to persistent memory/storage to avoid sudden loss of data in case power goes off completely. +* - Action 2. Stop heavy CPU consumption or power consumption activities to save remaining power. +*
APP_EVENT_DEVICE_ORIENT The orientation of device is changed. +* Recommended action is as follows: change display orientation to match display orientation +*
APP_EVANG_LANGUAGE_CHANGED The language setting is changed. +* Recommended action: refresh the display into the new language +*
APP_EVENT_REGION_FORMAT_CHANGED The region format setting changed. +* Region change means a different time zone; the application UI may need to update the time to reflect the time zone change. +*
+* +* @subsection CAPI_APPLICATION_MODULE_STATES_TRANSITIONS The Application States and Transitions +* The Tizen native application can be in one of the several different states. Typically, the application is launched by the user from the Launcher, or by +* another application. As the application is starting, app_create_cb() is executed, and then the main event loop starts. After executing event loop, app_control_cb() and app_resume_cb() will be invoked. +* The application now normally becomes the front-most window, with focus. When the application loses the front-most/focus status, the app_pause_cb() callback is invoked. There +* are many scenarios for your application to go into the pause state, which means your application is not terminated, but is running in the background: +* - A new application is launched from the request of your application +* - The user requests to go to the home screen +* - A system event occurs and it causes a resident application with higher priority (e.g. a phone call is received) to become active, and hides +* your application temporarily +* - An alarm went off for another application so it now becomes the top-most window and hides your application +* +* When your application becomes visible again, the app_resume_cb() callback is invoked. Some possible scenarios for your application to become visible are: +* - Another application requests your application to run (perhaps the Task Navigator which shows all running applications and lets +* the user select any app to run) +* - All applications on top of your application in the window stack finish +* - An alarm is going off for your application so it becomes the top-most window and hides other applications +* +* When your application starts exiting, the app_pause_cb() callback is invoked if the application is visible, and then the app_terminate_cb() callback is invoked. Possible scenarios to start termination of your application are: +* - Your application itself requests to exit by calling ui_app_exit() to terminate the event loop +* - The Low Memory Killer is killing your application in a low memory situation. +* +* Note that a service application doesn't have UI, so the service application doesn't have Paused state. +* +* Application state changes are managed by the underlying framework. +* Refer to the following state diagram to see the possible transitions: +* @image html capi_appfw_application_states.png "Application states" +*

+* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
State Description
READY The application is launched.
CREATED The application starts the main loop.
RUNNING The application is running and visible to the user.
PAUSED The application is running but invisible to the user.
TERMINATED The application is terminated
+* +* The Application API defines five states with their corresponding transition handlers. +* The state transition is notified through the state transition callback function, +* whether the application is created, is running, is paused, is resumed, or is terminated. +* And the application has to perform a specific task that is appropriate to those state changes. +* +* @image html capi_appfw_application_lifecycle.png "General application lifecycle" +* +* @subsection CAPI_APPLICATION_MODULE_HOW_TO_START How to start the Tizen native application +* An application can be launched by the user from the Launcher or by another application. +* +* Regardless of how an application is launched, the Application Framework starts an application by creating a new process and calls +* the entry point of the application. Like a conventional Linux application, the main function of its application is the entry point. +* In the Tizen application, the main task is to hand over control to the Application Framework by calling the ui_app_main() function. +* @code +* bool app_create(void *user_data) +* { +* // Hook to take necessary actions before the main event loop starts +* // Initialize UI resources and application's data +* // If this function returns @c true, the main loop of the application starts +* // If this function returns @c false, the application is terminated +* return true; +* } +* +* void app_control(app_control_h app_control, void *user_data) +* { +* // Handle the launch request +* } +* +* void app_pause(void *user_data) +* { +* // Take necessary actions when the application becomes invisible +* } +* +* void app_resume(void *user_data) +* { +* // Take necessary actions when the application becomes visible. +* } +* +* void app_terminate(void *user_data) +* { +* // Release all resources +* } +* +* int main(int argc, char *argv[]) +* { +* struct appdata ad; +* +* ui_app_lifecycle_callback_s event_callback = {0,}; +* +* event_callback.create = app_create; +* event_callback.terminate = app_terminate; +* event_callback.pause = app_pause; +* event_callback.resume = app_resume; +* event_callback.app_control = app_control; +* +* memset(&ad, 0x0, sizeof(struct appdata)); +* +* return ui_app_main(argc, argv, &event_callback, &ad); +* } +* @endcode +* +* The ui_app_main() function initializes the application and then starts the main loop. +* +* The ui_app_main() function takes four parameters and uses them to initialize the application. +* The @a argc and @a argv parameters contain the values from the Application Framework, so that you should never have to change the values. +* The third parameter is a state transition handler that is responsible for managing the state +* transitions that the application goes through while it is running. The fourth parameter is the application data to be passed to each state handler. +* +* When ui_app_main() is first invoked, the application moves from the ready state to the created state. +* The application has to initialize itself. +* +* During this transition, the Application Framework calls the application's app_create_cb() state transition callback function just +* before the application enters the main loop. Within the registered app_create_cb() callback function, you should initialize the +* application's resources and create the main window. +* +* If the app_create_cb() callback function returns @c false, the application moves to the terminated state.\n +* If the app_create_cb() callback function returns @c true, the application enters the main loop. +* +* @subsection CAPI_APPLICATION_MODULE_LAUNCH_OPTIONS Handling the launch options +* The Application Framework calls the application's app_control_cb() callback function just after the application enters the main loop. +* This callback function is passed to the app_control containing the reason due to which the application is launched. +* For example, the application might be launched to open a file to handle the request that has been sent by another application. +* In all of these cases, the application is responsible for checking the contents of the app_control and responding appropriately. The contents +* of the app_control can be empty in situations where the application is launched by the user from the Launcher. +* +* @code +* static void app_control(app_control_h app_control, void *user_data) +* { +* struct appdata *ad = (struct appdata *)user_data; +* char *operation; +* char *uri; +* char *mime_type; +* +* app_control_get_operation(app_control, operation); +* +* if (!strcmp(operation, SERVICE_OPERATION_VIEW)) +* { +* app_control_get_uri(app_control, &uri); +* app_control_get_mime(app_control, &mime_type); +* +* if (uri && !strcmp(mime_type, "image/jpg")) +* { +* display_image_file(ad, uri); // display a specific image file +* } +* } +* +* if (ad->win) +* elm_win_activate(ad->win); +* +* } +* @endcode +* +*/ + +#endif /* __TIZEN_APPFW_APP_DOC_H__ */ diff --git a/doc/appfw_i18n_doc.h b/doc/appfw_i18n_doc.h new file mode 100755 index 0000000..8b874f3 --- /dev/null +++ b/doc/appfw_i18n_doc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_I18N_DOC_H__ +#define __TIZEN_APPFW_I18N_DOC_H__ + + + /** + * @ingroup CAPI_APPLICATION_MODULE + * @defgroup CAPI_I18N_MODULE Internationalization + * @brief The Internationalization API provides functions to write multilingual applications through GNU gettext. + * + * @section CAPI_I18_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_I18N_MODULE_OVERVIEW Overview + * The @ref CAPI_I18N_MODULE API provides functions to write multilingual applications through GNU gettext. + *

+ * Tizen provides all the features of the GNU gettext library through the Internationalization API + * and allows you to manage message catalogs from SDK. + *

+ * The Internationalization API consists of i18n_get_text() for message translation + * and macros to use i18n_get_text() in an easy to use form. + * These macros allow you to mark strings for translation in source codes, + * which are replaced with the translated strings at runtime. + *

+ */ + + + +#endif /* __TIZEN_APPFW_I18N_DOC_H__ */ diff --git a/doc/appfw_preference_doc.h b/doc/appfw_preference_doc.h new file mode 100755 index 0000000..2b04552 --- /dev/null +++ b/doc/appfw_preference_doc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_PREFERENCE_DOC_H__ +#define __TIZEN_APPFW_PREFERENCE_DOC_H__ + + /** + * @ingroup CAPI_APPLICATION_MODULE + * @defgroup CAPI_PREFERENCE_MODULE Preference + * @brief The @ref CAPI_PREFERENCE_MODULE API provides functions to store and retrieve small pieces of data, used for application preferences. + * + * @addtogroup CAPI_PREFERENCE_MODULE + * + * @section CAPI_PREFERENCE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_PREFERENCE_MODULE_OVERVIEW Overview + * + * The Preference API provides a mechanism that saves data items in the form of key/value pairs for this application, and later retrieves them. + * A typical usecase would be for an application preference screen where the user can pick some values for some options. The Preference API + * has pairs of functions, one to set such a pair, another to retrieve the stored value given in the key. Keys are always text strings, but + * there are functions for each of the possible value types: integer, double, string, and boolean. There is also a function to clear all of the preferences. + * + * The @ref CAPI_PREFERENCE_MODULE API provides a way to register a callback to get notified when a value for a particular key changes. It is useful to know + * when the display should be updated or some behavior is altered as a result. + * + * There is an iterator function which steps through all the data pairs, invoking a callback for each one. + */ + +#endif /* __TIZEN_APPFW_PREFERENCE_DOC_H__ */ diff --git a/doc/images/capi_appfw_application_lifecycle.png b/doc/images/capi_appfw_application_lifecycle.png new file mode 100755 index 0000000000000000000000000000000000000000..840505c536b07d28e1b2ca79bd4e051c764bed0a GIT binary patch literal 30482 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 Nfu7MdjE-aE{{b=GZt4I4 literal 0 HcmV?d00001 diff --git a/doc/images/capi_appfw_application_states.png b/doc/images/capi_appfw_application_states.png new file mode 100755 index 0000000000000000000000000000000000000000..3bcec5ad5197c4ca87c7a2bca57c01131bf6e39f GIT binary patch literal 32111 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�y-%!v>1IlYzw46a*(RMSHLX!7~ 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 literal 0 HcmV?d00001 diff --git a/include/app.h b/include/app.h index 362178b..f1bb296 100755 --- a/include/app.h +++ b/include/app.h @@ -11,199 +11,190 @@ * 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. + * limitations under the License. */ #ifndef __TIZEN_APPFW_APP_H__ #define __TIZEN_APPFW_APP_H__ -#include -#include -#include -#include -#include +#include +#include #include -#include +#include #ifdef __cplusplus extern "C" { #endif /** - * @addtogroup CAPI_APPLICATION_MODULE - * @{ + * @file app.h */ - -/** - * @brief Enumerations of error code for Application. - */ -typedef enum -{ - APP_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - APP_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - APP_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - APP_ERROR_INVALID_CONTEXT = TIZEN_ERROR_NOT_PERMITTED, /**< Invalid application context */ - APP_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file or directory */ - APP_ERROR_ALREADY_RUNNING = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Application is already running */ -} app_error_e; - - /** - * @brief Enumerations of the device orientation. + * @addtogroup CAPI_APPLICATION_MODULE + * @{ */ -typedef enum -{ - APP_DEVICE_ORIENTATION_0 = 0, /**< The device is oriented in natural position */ - APP_DEVICE_ORIENTATION_90 = 90, /**< The device's left side is at the top */ - APP_DEVICE_ORIENTATION_180 = 180, /**< The device is upside down */ - APP_DEVICE_ORIENTATION_270 = 270, /** #include -#include +#include #ifdef __cplusplus extern "C" { #endif /** + * @file app_alarm.h + */ + +/** * @addtogroup CAPI_ALARM_MODULE * @{ */ /** - * @brief Service extra data : the id of the alarm registered + * @brief Definition to app_control extra data : the ID of the alarm registered. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ -#define SERVICE_DATA_ALARM_ID "http://tizen.org/appcontrol/data/alarm_id" +#define APP_CONTROL_DATA_ALARM_ID "http://tizen.org/appcontrol/data/alarm_id" /** - * @brief Enumerations of error codes for the alarm + * @brief Enumeration for Alarm Error. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { ALARM_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ ALARM_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - ALARM_ERROR_INVALID_TIME = TIZEN_ERROR_APPLICATION_CLASS | 0x05, /**< Invalid time */ - ALARM_ERROR_INVALID_DATE = TIZEN_ERROR_APPLICATION_CLASS | 0x06, /**< Invalid date */ - ALARM_ERROR_CONNECTION_FAIL = TIZEN_ERROR_APPLICATION_CLASS | 0x07, /**< The alarm service connection failed */ - ALARM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY /**< Out of memory */ + ALARM_ERROR_INVALID_TIME = TIZEN_ERROR_APPLICATION | 0x05, /**< Invalid time */ + ALARM_ERROR_INVALID_DATE = TIZEN_ERROR_APPLICATION | 0x06, /**< Invalid date */ + ALARM_ERROR_CONNECTION_FAIL = TIZEN_ERROR_APPLICATION | 0x07, /**< The alarm service connection failed */ + ALARM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + ALARM_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED /**< Permission denied */ } alarm_error_e; /** - * @brief Enumerations of the days of the week. + * @brief Enumeration for Alarm Week Flag, the days of the week. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -65,105 +73,128 @@ typedef enum } alarm_week_flag_e; /** - * @brief Called once for each scheduled alarm to get the alarm ID. + * @brief Called once for each scheduled alarm to get the alarm ID. * - * @param[in] alarm_id The alarm ID returned when the alarm is scheduled - * @param[in] user_data The user data passed from the foreach function - * @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. - * @pre alarm_foreach_registered_alarm() will invoke this callback to get all registered alarm IDs. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] alarm_id The alarm ID returned when the alarm is scheduled + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre alarm_foreach_registered_alarm() will invoke this callback to get all the registered alarm IDs. * @see alarm_foreach_registered_alarm() */ typedef bool (*alarm_registered_alarm_cb)(int alarm_id, void *user_data); /** - * @brief Sets an alarm to be triggered after specific time. + * @brief Sets an alarm to be triggered after a specific time. * @details The alarm will first go off @a delay seconds later and then will go off every certain amount of time defined using @a period seconds. - * If @a period is bigger than 0, the alarm will be scheduled after the @a period time. - * If @a period is set to 0, the alarm will go off just once without repetition. - * To cancel the alarm, call alarm_cancel() with @alarm_id + * If @a period is bigger than @c 0, the alarm will be scheduled after the @a period time. + * If @a period is set to @c 0, the alarm will go off just once without repetition. + * To cancel the alarm, call alarm_cancel() with @a alarm_id. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.set + * @remarks If the application is uninstalled after setting an alarm, the alarm is cancelled automatically. * - * @remarks If application is uninstalled after setting an alarm, the alarm is canceled automatically. - * - * @param[in] service The destination service to perform specific work when the alarm is triggered. - * @param[in] delay The amount of time before first execution(in second) - * @param[in] period The amount of time between subsequent alarms(in second) - * @param[out] alarm_id The alarm ID uniquely identifies an alarm - * @return 0 on success, otherwise a negative error value. + * @param[in] app_control The destination app_control to perform a specific task when the alarm is triggered + * @param[in] delay The amount of time before the first execution (in seconds) + * @param[in] period The amount of time between subsequent alarms (in seconds) + * @param[out] alarm_id The alarm ID that uniquely identifies an alarm + * @return @c 0 on success, + * otherwise a negative error value * @retval #ALARM_ERROR_NONE Successful * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter * @retval #ALARM_ERROR_INVALID_TIME Triggered time is invalid * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_cancel() * @see alarm_cancel_all() * @see alarm_get_scheduled_date() * @see alarm_get_scheduled_period() */ -int alarm_schedule_after_delay(service_h service, int delay, int period, int *alarm_id); +int alarm_schedule_after_delay(app_control_h app_control, int delay, int period, int *alarm_id); /** - * @brief Sets an alarm to be triggered at a specific time. - * @details - * The @a date describes the time of first occurrence. - * If @a period is bigger than 0, the alarm will be scheduled after the @a period time. - * If @a period is set to 0, the alarm will go off just once without repetition. - * To cancel the alarm, call alarm_cancel() with alarm id + * @brief Sets an alarm to be triggered at a specific time. + * @details The @a date describes the time of the first occurrence. + * If @a period is bigger than @c 0, the alarm will be scheduled after the @a period time. + * If @a period is set to @c 0, the alarm will go off just once without repetition. + * To cancel the alarm, call alarm_cancel() with @a alarm_id. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.set + * @remarks If application is uninstalled after setting an alarm, the alarm is cancelled automatically. + * If the operation of @a app_control is not specified, #APP_CONTROL_OPERATION_DEFAULT is used for the launch request. + * If the operation of @a app_control is #APP_CONTROL_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application. * - * @remarks If application is uninstalled after setting an alarm, the alarm is canceled automatically. - * - * @param[in] service The destination service to perform specific work when the alarm is triggered + * @param[in] app_control The destination app_control to perform specific work when the alarm is triggered * @param[in] date The first active alarm time * @param[in] period The amount of time between subsequent alarms(in second) - * @param[out] alarm_id The alarm ID uniquely identifies an alarm - * @return 0 on success, otherwise a negative error value. + * @param[out] alarm_id The alarm ID that uniquely identifies an alarm + * @return @c 0 on success, + * otherwise a negative error value * @retval #ALARM_ERROR_NONE Successful * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter * @retval #ALARM_ERROR_INVALID_DATE Triggered date is invalid * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_cancel() * @see alarm_cancel_all() * @see alarm_get_scheduled_date() * @see alarm_get_scheduled_period() */ -int alarm_schedule_at_date(service_h service, struct tm *date, int period, int *alarm_id); - +int alarm_schedule_at_date(app_control_h app_control, struct tm *date, int period, int *alarm_id); /** - * @brief Sets an alarm to be triggered at a specific time with recurrence repeat. - * @details - * The @a date describes the time of first occurrence. - * @a week_flag is the repeat value of days of the week. If @a week_flag is #ALARM_WEEK_FLAG_TUESDAY, the alarm will repeat at every Tuesday specific time. - * To cancel the alarm, call alarm_cancel() with the @alarm_id - * @remarks If application is uninstalled after setting an alarm, the alarm is canceled automatically. + * @brief Sets an alarm to be triggered periodically, starting at a specific time. + * @details The @a date describes the time of the first occurrence. + * @a week_flag is the repeat value of the days of the week. + * If @a week_flag is #ALARM_WEEK_FLAG_TUESDAY, the alarm will repeat every Tuesday at a specific time. + * To cancel the alarm, call alarm_cancel() with @a alarm_id. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.set + * @remarks If the application is uninstalled after setting an alarm, the alarm is cancelled automatically. + * If the operation of @a app_control is not specified, #APP_CONTROL_OPERATION_DEFAULT is used for the launch request. + * If the operation of @a app_control is #APP_CONTROL_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application. * - * @param[in] service The destination service to perform specific work when the alarm is triggered. - * @param[in] date The first active alarm time - * @param[in] week_flag The day of the week, @a week_flag may be a combination of days, like #ALARM_WEEK_FLAG_TUESDAY | #ALARM_WEEK_FLAG_FRIDAY. - * @param[out] alarm_id The alarm ID uniquely identifies an alarm - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #ALARM_ERROR_INVALID_DATE Triggered date is invalid - * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @param[in] app_control The destination app_control to perform specific work when the alarm is triggered + * @param[in] date The first active alarm time + * @param[in] week_flag The day of the week, @a week_flag may be a combination of days, like #ALARM_WEEK_FLAG_TUESDAY | #ALARM_WEEK_FLAG_FRIDAY + * @param[out] alarm_id The alarm ID that uniquely identifies an alarm + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_INVALID_DATE Triggered date is invalid + * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_cancel() * @see alarm_cancel_all() * @see alarm_get_scheduled_recurrence_week_flag() - * @see alarm_get_scheduled_recurrence_week_flag() * @see alarm_get_scheduled_date() * @see #alarm_week_flag_e */ -int alarm_schedule_with_recurrence_week_flag(service_h service, struct tm *date, int week_flag,int *alarm_id); +int alarm_schedule_with_recurrence_week_flag(app_control_h app_control, struct tm *date, int week_flag,int *alarm_id); /** * @brief Gets the recurrence days of the week. - * @remarks If the given @a alarm_id is not obtained by using the alarm_schedule_with_recurrence_week_flag() function, - * an error (error code #ALARM_ERROR_INVALID_PARAMETER) will occur because this alarm is scheduled with no recurrence. - * @param[in] alarm_id The alarm ID returned when the alarm is scheduled - * @param[out] week_flag The recurrence days of the week, @a week_flag may be a combination of days, like #ALARM_WEEK_FLAG_TUESDAY | #ALARM_WEEK_FLAG_FRIDAY. - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.get + * @remarks If the given @a alarm_id is not obtained by using the alarm_schedule_with_recurrence_week_flag() function, + * an error (error code #ALARM_ERROR_INVALID_PARAMETER) will occur because this alarm is scheduled with no recurrence. + * If the operation of @a app_control is not specified, #APP_CONTROL_OPERATION_DEFAULT is used for the launch request. + * If the operation of @a app_control is #APP_CONTROL_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application. + * @param[in] alarm_id The alarm ID returned when the alarm is scheduled + * @param[out] week_flag The recurrence days of the week, @a week_flag may be a combination of days, like #ALARM_WEEK_FLAG_TUESDAY | #ALARM_WEEK_FLAG_FRIDAY + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_with_recurrence_week_flag() * @see #alarm_week_flag_e */ @@ -171,11 +202,16 @@ int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag); /** - * @brief Cancels the alarm with the specific alarm ID. - * @param[in] alarm_id The alarm ID that will be canceled - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @brief Cancels the alarm with the specific alarm ID. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.set + * @param[in] alarm_id The alarm ID that is cancelled + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_at_date() * @see alarm_schedule_after_delay() * @see alarm_schedule_with_recurrence_week_flag() @@ -185,11 +221,15 @@ int alarm_cancel(int alarm_id); /** - * @brief Cancels all alarms scheduled. - * - * @return 0 on success, otherwise a negative error value. + * @brief Cancels all scheduled alarms that are registered by the application that calls this API. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.set + * @return @c 0 on success, + * otherwise a negative error value * @retval #ALARM_ERROR_NONE Successful * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_at_date() * @see alarm_schedule_after_delay() * @see alarm_schedule_with_recurrence_week_flag() @@ -199,29 +239,37 @@ int alarm_cancel_all(void); /** - * @brief Retrieves the IDs of all registered alarms by invoking callback once for each scheduled alarm. - * - * @param[in] callback The callback function to invoke - * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server - * @post This function invokes alarm_registered_alarm_cb() repeatedly for each registered alarm. + * @brief Retrieves the IDs of all registered alarms by invoking a callback once for each scheduled alarm. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.get + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied + * @post This function invokes alarm_registered_alarm_cb() repeatedly for each registered alarm. * @see alarm_registered_alarm_cb() */ int alarm_foreach_registered_alarm(alarm_registered_alarm_cb callback, void *user_data); /** - * @brief Gets the scheduled time from the given alarm ID in C standard time struct. - * - * @param[in] alarm_id The alarm ID returned when the alarm is scheduled - * @param[out] date The time value of next alarm event - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @brief Gets the scheduled time from the given alarm ID in C standard time struct. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.get + * @param[in] alarm_id The alarm ID returned when the alarm is scheduled + * @param[out] date The time value of the next alarm event + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_at_date() * @see alarm_schedule_after_delay() * @see alarm_schedule_with_recurrence_week_flag() @@ -230,15 +278,20 @@ int alarm_get_scheduled_date(int alarm_id, struct tm *date); /** - * @brief Gets the period of time between the recurrent alarms. - * @remarks If the given @a alarm_id is not obtained by using the alarm_get_scheduled_date() or alarm_schedule_after_delay() function, - * an error (error code #ALARM_ERROR_INVALID_PARAMETER) will occur. - * @param[in] alarm_id The alarm ID returned when the alarm is scheduled - * @param[out] period The period of time between recurrent alarms in seconds - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @brief Gets the period of time between the recurrent alarms. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.get + * @remarks If the given @a alarm_id is not obtained by using the alarm_get_scheduled_date() or alarm_schedule_after_delay() function, + * an error (error code #ALARM_ERROR_INVALID_PARAMETER) will occur. + * @param[in] alarm_id The alarm ID returned when the alarm is scheduled + * @param[out] period The period of time between recurrent alarms in seconds + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_CONNECTION_FAIL Failed to connect to an alarm server + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_at_date() * @see alarm_schedule_after_delay() * @see alarm_schedule_with_recurrence_week_flag() @@ -247,30 +300,37 @@ int alarm_get_scheduled_period(int alarm_id, int *period); /** - * @brief Gets the current system time using C standard time struct. - * + * @brief Gets the current system time using C standard time struct. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[out] date The current system time - * @return 0 on success, otherwise a negative error value. - * @retval #ALARM_ERROR_NONE Successful - * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @return @c 0 on success, + * otherwise a negative error value + * @retval #ALARM_ERROR_NONE Successful + * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied */ int alarm_get_current_time(struct tm *date); /** - * @brief Gets the service to be invoked when the the alarm is triggered - * @remarks The @a service must be released with service_destroy() by you. - * @param[in] alarm_id The alarm ID uniquely identifies an alarm - * @param[out] service The service handle to launch when the alarm is triggered - * @return 0 on success, otherwise a negative error value. + * @brief Gets the app_control to be invoked when the the alarm is triggered. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/alarm.get + * @remarks The @a app_control must be released using app_control_destroy(). + * @param[in] alarm_id The alarm ID uniquely identifies an alarm + * @param[out] app_control The app_control handle to launch when the alarm is triggered + * @return @c 0 on success, + * otherwise a negative error value * @retval #ALARM_ERROR_NONE Successful * @retval #ALARM_ERROR_INVALID_PARAMETER Invalid parameter * @retval #ALARM_ERROR_OUT_OF_MEMORY Out of memory + * @retval #ALARM_ERROR_PERMISSION_DENIED Permission denied * @see alarm_schedule_at_date() * @see alarm_schedule_after_delay() * @see alarm_schedule_with_recurrence_week_flag() */ -int alarm_get_service(int alarm_id, service_h *service); +int alarm_get_app_control(int alarm_id, app_control_h *app_control); /** * @} diff --git a/include/app_common.h b/include/app_common.h new file mode 100644 index 0000000..f025299 --- /dev/null +++ b/include/app_common.h @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2014 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 __TIZEN_APPFW_APP_COMMON_H__ +#define __TIZEN_APPFW_APP_COMMON_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file app_common.h + */ + +/** + * @addtogroup CAPI_APP_COMMON_MODULE + * @{ + */ + + +/** + * @brief Enumeration for system events + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_EVENT_LOW_MEMORY, /**< The low memory event */ + APP_EVENT_LOW_BATTERY, /**< The low battery event */ + APP_EVENT_LANGUAGE_CHANGED, /**< The system language changed event */ + APP_EVENT_DEVICE_ORIENTATION_CHANGED, /**< The device orientation changed event */ + APP_EVENT_REGION_FORMAT_CHANGED, /**< The region format changed event */ +} app_event_type_e; + + +/** + * @brief Enumeration for device orientation. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_DEVICE_ORIENTATION_0 = 0, /**< The device is oriented in a natural position */ + APP_DEVICE_ORIENTATION_90 = 90, /**< The device's left side is at the top */ + APP_DEVICE_ORIENTATION_180 = 180, /**< The device is upside down */ + APP_DEVICE_ORIENTATION_270 = 270, /**< The device's right side is at the top */ +} app_device_orientation_e; + + +/** + * @brief Enumeration for low memory status. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_EVENT_LOW_MEMORY_NORMAL = 0x01, /**< Normal status */ + APP_EVENT_LOW_MEMORY_SOFT_WARNING = 0x02, /**< Soft warning status */ + APP_EVENT_LOW_MEMORY_HARD_WARNING = 0x04, /**< Hard warning status */ +} app_event_low_memory_status_e; + + +/** + * @brief Enumeration for battery status. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_EVENT_LOW_BATTERY_POWER_OFF = 1, /**< The battery status is under 1% */ + APP_EVENT_LOW_BATTERY_CRITICAL_LOW, /**< The battery status is under 5% */ +} app_event_low_battery_status_e; + + +/** + * @brief The event handler that returned from add event handler function + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @see app_event_type_e + * @see app_add_event_handler + * @see app_remove_event_handler + * @see app_event_info_h + */ +typedef struct app_event_handler* app_event_handler_h; + + +/** + * @brief The system event information + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @see app_event_get_low_memory_status + * @see app_event_get_low_battery_status + * @see app_event_get_language + * @see app_event_get_region_format + * @see app_event_get_device_orientation + */ +typedef struct app_event_info* app_event_info_h; + + +/** + * @brief The system event callback function + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] event_info The system event information + * @param[in] user_data The user data passed from the add event handler function + * + * @see app_add_event_handler + * @see app_event_info_h + */ +typedef void (*app_event_cb)(app_event_info_h event_info, void *user_data); + + +/** + * @brief Gets the low memory status from given event info + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] event_info The system event info + * @param[out] status The low memory status + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT Invalid event context + * + * @see app_event_info_h + * @see app_event_low_memory_status_e + */ +int app_event_get_low_memory_status(app_event_info_h event_info, app_event_low_memory_status_e *status); + + +/** + * @brief Gets the low battery status from given event info + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] event_info The system event info + * @param[out] status The low battery status + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT Invalid event context + * + * @see app_event_info_h + * @see app_event_low_battery_status_e + */ +int app_event_get_low_battery_status(app_event_info_h event_info, app_event_low_battery_status_e *status); + + +/** + * @brief Gets the language from given event info + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a lang must be released using free() + * @param[in] event_info The system event info + * @param[out] lang The language changed + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT Invalid event context + * + * @see app_event_info_h + */ +int app_event_get_language(app_event_info_h event_info, char **lang); + + +/** + * @brief Gets the region format from given event info + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a region must be released using free() + * @param[in] event_info The system event info + * @param[out] region The region format changed + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT Invalid event context + * + * @see app_event_info_h + */ +int app_event_get_region_format(app_event_info_h event_info, char **region); + + +/** + * @brief Gets the device orientation from given event info + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] event_info The system event info + * @param[out] orientation The device orientation changed + * + * @return 0 on success, otherwise a negative error value + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT Invalid event context + * + * @see app_event_info_h + * @see app_device_orientation_e + */ +int app_event_get_device_orientation(app_event_info_h event_info, app_device_orientation_e *orientation); + + +/** + * @brief Gets the ID of the application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a id must be released using free(). + * + * @param[out] id The ID of the application + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT The application is illegally launched, not launched by the launch system + * @retval #APP_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_get_id(char **id); + + +/** + * @brief Gets the localized name of the application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a name must be released using free(). + * + * @param[out] name The name of the application + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT The application is illegally launched, not launched by the launch system + * @retval #APP_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_get_name(char **name); + + +/** + * @brief Gets the version of the application package. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a version must be released using free(). + * + * @param[out] version The version of the application + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #APP_ERROR_NONE Successful + * @retval #APP_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_ERROR_INVALID_CONTEXT The application is illegally launched, not launched by the launch system + * @retval #APP_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_get_version(char **version); + + +/** + * @brief Gets the absolute path to the application's data directory which is used to store private + * data of the application. + * @details An application can read and write its own files in the application's data directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. + * + * @return The absolute path to the application's data directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_data_path(void); + + +/** + * @brief Gets the absolute path to the application's cache directory which is used to store + * temporary data of the application. + * @details An application can read and write its own files in the application's cache directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. @n + * The files stored in the application's cache directory can be removed by Setting + * application or platform while the application is running. + * + * @return The absolute path to the application's cache directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_cache_path(void); + + +/** + * @brief Gets the absolute path to the application resource directory. The resource files + * are delivered with the application package. + * @details An application can only read its own files in the application's resource directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. + * + * @return The absolute path to the application's resource directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_resource_path(void); + + +/** + * @brief Gets the absolute path to the application's shared data directory which is used to share + * data with other applications. + * @details An application can read and write its own files in the application's shared data + * directory and others can only read the files. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. + * + * @return The absolute path to the application's shared data directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_shared_data_path(void); + + +/** + * @brief Gets the absolute path to the application's shared resource directory which is used to + * share resources with other applications. + * @details An application can read its own files in the application's shared resource directory + * and others can only read the files. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. + * + * @return The absolute path to the application's shared resource directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_shared_resource_path(void); + + +/** + * @brief Gets the absolute path to the application's shared trusted directory which is used to share data + * with a family of trusted applications. + * @details An application can read and write its own files in the application's shared trusted directory + * and the family applications signed with the same certificate can read and write the files in the + * shared trusted directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. + * + * @return The absolute path to the application's shared trusted directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_shared_trusted_path(void); + + +/** + * @brief Gets the absolute path to the application's external data directory which is used to + * store data of the application. + * @details An application can read and write its own files in the application's external data + * directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. @n + * The important files stored in the application's external data directory should be + * encrypted because they can be exported via the external sdcard. + * + * @return The absolute path to the application's external data directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_external_data_path(void); + + +/** + * @brief Gets the absolute path to the application's external cache directory which is used to + * store temporary data of the application. + * @details An application can read and write its own files in the application's external cache + * directory. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The returned path should be released. @n + * The files stored in the application's external cache directory can be removed by + * Setting application while the application is running. @n + * The important files stored in the application's external cache directory should be + * encrypted because they can be exported via the external sdcard. + * + * @return The absolute path to the application's external cache directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_external_cache_path(void); + + +/** + * @brief Gets the absolute path to the application's external shared data directory which is + * used to share data with other applications. + * @details An application can read and write its own files in the application's external shared + * data directory and others can only read the files. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The specified @a path should be released. + * + * @return The absolute path to the application's external shared data directory, @n + * otherwise a null pointer if the memory is insufficient + */ +char *app_get_external_shared_data_path(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_APP_H__ */ diff --git a/include/app_control.h b/include/app_control.h new file mode 100755 index 0000000..83eddb7 --- /dev/null +++ b/include/app_control.h @@ -0,0 +1,877 @@ +/* + * Copyright (c) 2014 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 __TIZEN_APPFW_APP_CONTROL_H__ +#define __TIZEN_APPFW_APP_CONTROL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file app_control.h + */ + +/** + * @addtogroup CAPI_APP_CONTROL_MODULE + * @{ + */ + + +typedef struct _bundle_t bundle; + + +/** + * @brief App Control handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct app_control_s* app_control_h; + + +/** + * @brief Enumeration for App Control Error. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_CONTROL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + APP_CONTROL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + APP_CONTROL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + APP_CONTROL_ERROR_APP_NOT_FOUND = TIZEN_ERROR_APPLICATION | 0x21, /**< The application is not found */ + APP_CONTROL_ERROR_KEY_NOT_FOUND = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Specified key is not found */ + APP_CONTROL_ERROR_KEY_REJECTED = TIZEN_ERROR_KEY_REJECTED, /**< Key is not available */ + APP_CONTROL_ERROR_INVALID_DATA_TYPE = TIZEN_ERROR_APPLICATION | 0x22, /**< Invalid data type */ + APP_CONTROL_ERROR_LAUNCH_REJECTED = TIZEN_ERROR_APPLICATION | 0x23, /**< The application cannot be launched now*/ + APP_CONTROL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + APP_CONTROL_ERROR_LAUNCH_FAILED = TIZEN_ERROR_APPLICATION | 0x24, /**< Internal launch error */ + APP_CONTROL_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT /**< Time out */ +} app_control_error_e; + + +/** + * @brief Enumeration for App Control Result. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef enum +{ + APP_CONTROL_RESULT_SUCCEEDED = 0, /**< Operation succeeded */ + APP_CONTROL_RESULT_FAILED = -1, /**< Operation failed by the callee */ + APP_CONTROL_RESULT_CANCELED = -2, /**< Operation canceled by the framework */ +} app_control_result_e; + + +/** + * @brief Definition for the app_control operation: main operation for an explicit launch. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_MAIN "http://tizen.org/appcontrol/operation/main" + + +/** + * @brief Definition for the app_control operation: default operation for an explicit launch. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_DEFAULT "http://tizen.org/appcontrol/operation/default" + + +/** + * @brief Definition for the app_control operation: provides an explicit editable access to the given data. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_EDIT "http://tizen.org/appcontrol/operation/edit" + + +/** + * @brief Definition for the app_control operation: displays the data. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_VIEW "http://tizen.org/appcontrol/operation/view" + + +/** + * @brief Definition for the app_control operation: picks an item from the data, returning what is selected. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_PICK "http://tizen.org/appcontrol/operation/pick" + + +/** + * @brief Definition for the app_control operation: creates content, returning what is created. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_CREATE_CONTENT "http://tizen.org/appcontrol/operation/create_content" + + +/** + * @brief Definition for the app_control operation: performs a call to someone specified by the data. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/call + * @remarks When you request this operation, you must declare this privilege. + */ +#define APP_CONTROL_OPERATION_CALL "http://tizen.org/appcontrol/operation/call" + + +/** + * @brief Definition for the app_control operation: delivers some data to someone else. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_SEND "http://tizen.org/appcontrol/operation/send" + + +/** + * @brief Definition for the app_control operation: delivers text data to someone else. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_SEND_TEXT "http://tizen.org/appcontrol/operation/send_text" + + +/** + * @brief Definition for the app_control operation: shares an item with someone else. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_SHARE "http://tizen.org/appcontrol/operation/share" + + +/** + * @brief Definition for the app_control operation: shares multiple items with someone else. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_MULTI_SHARE "http://tizen.org/appcontrol/operation/multi_share" + + +/** + * @brief Definition for the app_control operation: shares text data with someone else. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_SHARE_TEXT "http://tizen.org/appcontrol/operation/share_text" + + +/** + * @brief Definition for the app_control operation: dials a number as specified by the data. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_DIAL "http://tizen.org/appcontrol/operation/dial" + + +/** + * @brief Definition for the app_control operation: performs a search. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_SEARCH "http://tizen.org/appcontrol/operation/search" + + +/** + * @brief Definition for the app_control operation: downloads an item. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_DOWNLOAD "http://tizen.org/appcontrol/operation/download" + + +/** + * @brief Definition for the app_control operation: prints content. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_PRINT "http://tizen.org/appcontrol/operation/print" + +/** + * @brief Definition for the app_control operation: composes. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_OPERATION_COMPOSE "http://tizen.org/appcontrol/operation/compose" + +/** + * @brief Definition for app_control optional data: the subject of a message. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_SUBJECT "http://tizen.org/appcontrol/data/subject" + + +/** + * @brief Definition for app_control optional data: e-mail addresses. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_TO "http://tizen.org/appcontrol/data/to" + + +/** + * @brief Definition for app_control optional data: e-mail addresses that should be carbon copied. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_CC "http://tizen.org/appcontrol/data/cc" + + +/** + * @brief Definition for app_control optional data: e-mail addresses that should be blind carbon copied. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_BCC "http://tizen.org/appcontrol/data/bcc" + + +/** + * @brief Definition for app_control optional data: the content of the data is associated with #APP_CONTROL_OPERATION_SEND. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_TEXT "http://tizen.org/appcontrol/data/text" + + +/** + * @brief Definition for app_control optional data: the title of the data. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_TITLE "http://tizen.org/appcontrol/data/title" + + +/** + * @brief Definition for app_control optional data: the path of a selected item. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_SELECTED "http://tizen.org/appcontrol/data/selected" + + +/** + * @brief Definition for app_control optional data: multiple item path to deliver. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_PATH "http://tizen.org/appcontrol/data/path" + + +/** + * @brief Definition for app_control optional data: the selection type. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +#define APP_CONTROL_DATA_SELECTION_MODE "http://tizen.org/appcontrol/data/selection_mode" + + +/** + * @brief Called when the reply of the launch request is delivered. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks The @a request and @a reply must not be deallocated by the application. + * + * @param[in] request The app_control handle of the launch request that has been sent + * @param[in] reply The app_control handle in which the results of the callee are contained + * @param[in] result The result code of the launch request + * @param[in] user_data The user data passed from the callback registration function + * @pre When the callee replies to the launch request, this callback will be invoked. + * @see app_control_send_launch_request() + * @see app_control_reply_to_launch_request() + */ +typedef void (*app_control_reply_cb) (app_control_h request, app_control_h reply, app_control_result_e result, void *user_data); + + +/** + * @brief Called to retrieve the extra data contained in the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * + * @remarks The @a key must not be deallocated by the application. + * + * @param[in] app_control The app_control handle + * @param[in] key The key of the value contained in the app_control + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre app_control_foreach_extra_data() will invoke this callback. + * @see app_control_foreach_extra_data() + */ +typedef bool (*app_control_extra_data_cb)(app_control_h app_control, const char *key, void *user_data); + + +/** + * @brief Called once for each matched application that can be launched to handle the given app_control request. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] package The package name of the application that can handle the launch request of the given app_control + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre app_control_foreach_app_matched() will invoke this callback. + * @see app_control_foreach_app_matched() + */ +typedef bool (*app_control_app_matched_cb)(app_control_h app_control, const char *appid, void *user_data); + + +typedef int (*app_control_host_res_fn)(void *data); + +/** + * @brief Creates an app_control handle. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a app_control must be released using app_control_destroy(). + * @param[out] app_control The app_control handle to be newly created on success + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_destroy() + */ +int app_control_create(app_control_h *app_control); + + +/** + * @brief Destroys the app_control handle and releases all its resources. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_create() + */ +int app_control_destroy(app_control_h app_control); + + +/** + * @internal + * @brief Converts the app_control handle to bundle data. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[out] data The bundle data on success + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + */ +int app_control_to_bundle(app_control_h app_control, bundle **data); + +/** + * @brief Sets the operation to be performed. + * + * @details The @a operation is the mandatory information for the launch request. + * If the operation is not specified, #APP_CONTROL_OPERATION_DEFAULT is used for the launch request. + * If the operation is #APP_CONTROL_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] operation The operation to be performed (if the @a operation is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_operation() + * @see APP_CONTROL_OPERATION_DEFAULT + * @see APP_CONTROL_OPERATION_EDIT + * @see APP_CONTROL_OPERATION_VIEW + * @see APP_CONTROL_OPERATION_PICK + * @see APP_CONTROL_OPERATION_CREATE_CONTENT + * @see APP_CONTROL_OPERATION_CALL + * @see APP_CONTROL_OPERATION_SEND + * @see APP_CONTROL_OPERATION_SEND_TEXT + * @see APP_CONTROL_OPERATION_DIAL + * @see APP_CONTROL_OPERATION_SEARCH + */ +int app_control_set_operation(app_control_h app_control, const char *operation); + + +/** + * @brief Gets the operation to be performed. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a operation must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] operation The operation to be performed + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_operation() + */ +int app_control_get_operation(app_control_h app_control, char **operation); + + +/** + * @brief Sets the URI of the data. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] uri The URI of the data this app_control is operating on (if the @a uri is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_uri() + */ +int app_control_set_uri(app_control_h app_control, const char *uri); + + +/** + * @brief Gets the URI of the data. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a uri must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] uri The URI of the data this app_control is operating on + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_uri() + */ +int app_control_get_uri(app_control_h app_control, char **uri); + + +/** + * @brief Sets the explicit MIME type of the data. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] mime The explicit MIME type of the data this app_control is operating on (if the @a mime is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_mime() + */ +int app_control_set_mime(app_control_h app_control, const char *mime); + + +/** + * @brief Gets the explicit MIME type of the data. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a uri must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] mime The explicit MIME type of the data this app_control is operating on + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_mime() + */ +int app_control_get_mime(app_control_h app_control, char **mime); + + +/** + * @brief Sets the explicit category. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] category The explicit category (if the @a category is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_get_category() + */ +int app_control_set_category(app_control_h app_control, const char *category); + + +/** + * @brief Gets the explicit category. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a category must be released using free(). + * @param[in] app_control The app_control handle + * @param[out] category The explicit category + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_category() + */ +int app_control_get_category(app_control_h app_control, char **category); + + +/** + * @brief Sets the ID of the application to explicitly launch. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] app_id The ID of the application to explicitly launch (if the @a app_id is @c NULL, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_get_app_id() + */ +int app_control_set_app_id(app_control_h app_control, const char *app_id); + + +/** + * @brief Gets the ID of the application to explicitly launch. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a app_id must be released with free(). + * @param[in] app_control The app_control handle + * @param[out] app_id The ID of the application to explicitly launch + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_app_id() + */ +int app_control_get_app_id(app_control_h app_control, char **app_id); + +/** + * @internal + * @brief Sets the window ID of the application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] id The window ID of the caller application (if the @a id is not positive, it clears the previous value) + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_get_window() + */ +int app_control_set_window(app_control_h app_control, unsigned int id); + + +/** + * @internal + * @brief Gets the window ID of the application. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[out] id The window ID of the caller application + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_set_app_id() +*/ +int app_control_get_window(app_control_h app_control, unsigned int *id); + + +/** + * @brief Adds extra data to the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The function replaces any existing value for the given key. + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if @a key or @a value is a zero-length string. + * @remarks The function returns #APP_CONTROL_ERROR_KEY_REJECTED if the application tries to use the same key with system-defined key. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[in] value The value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_REJECTED Key not available + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_get_extra_data() + */ +int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value); + + +/** + * @brief Adds the extra data array to the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The function replaces any existing value for the given key. + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if @a key is a zero-length string. + * @remarks The function returns #APP_CONTROL_ERROR_KEY_REJECTED if the application tries to use the same key with system-defined key. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[in] value The array value associated with the given key + * @param[in] length The length of the array + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_REJECTED Key not available + * @see app_control_add_extra_data() + * @see app_control_remove_extra_data() + * @see app_control_get_extra_data() + */ +int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length); + + +/** + * @brief Removes the extra data from the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_get_extra_data() + */ +int app_control_remove_extra_data(app_control_h app_control, const char *key); + + +/** + * @brief Gets the extra data from the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a value must be released using free(). + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_DATA_TYPE if @a value is of array data type. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] value The value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_INVALID_DATA_TYPE Invalid data type + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_get_extra_data() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_get_extra_data(app_control_h app_control, const char *key, char **value); + + +/** + * @brief Gets the extra data array from the app_control. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a value must be released using free(). + * @remarks The function returns #APP_CONTROL_ERROR_INVALID_DATA_TYPE if @a value is not of array data type. + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] value The array value associated with the given key + * @param[out] length The length of the array + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_KEY_NOT_FOUND Specified key not found + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_INVALID_DATA_TYPE Invalid data type + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length); + + +/** + * @brief Checks whether the extra data associated with the given @a key is of array data type. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] key The name of the extra data + * @param[out] array If @c true the extra data is of array data type, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_add_extra_data() + * @see app_control_add_extra_data_array() + * @see app_control_remove_extra_data() + * @see app_control_foreach_extra_data() + */ +int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array); + + +/** + * @brief Retrieves all extra data contained in app_control. + * @details This function calls app_control_extra_data_cb() once for each key-value pair for extra data contained in app_control. \n + * If the app_control_extra_data_cb() callback function returns @c false, then iteration will be finished. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] callback The iteration callback function + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @post This function invokes app_control_extra_data_cb(). + * @see app_control_extra_data_cb() + */ +int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data); + + +/** + * @brief Retrieves all applications that can be launched to handle the given app_control request. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @param[in] callback The iteration callback function + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Success + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @post This function invokes app_control_app_matched_cb(). + * @see app_control_app_matched_cb() + */ +int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data); + + +/** + * @brief Sends the launch request. + * + * @details The operation is mandatory information for the launch request. \n + * If the operation is not specified, #APP_CONTROL_OPERATION_DEFAULT is used by default. + * If the operation is #APP_CONTROL_OPERATION_DEFAULT, the application ID is mandatory to explicitly launch the application. + * @remarks In some implementations of the Tizen platform, service applications are only allowed to be launched explicitly by the application in the same package; hence you should not use this function to launch the service application that is not in the your application package. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @privlevel public + * @privilege %http://tizen.org/privilege/appmanager.launch + * @param[in] app_control The app_control handle + * @param[in] callback The callback function to be called when the reply is delivered + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @retval #APP_CONTROL_ERROR_APP_NOT_FOUND The application to run the given launch request is not found + * @retval #APP_CONTROL_ERROR_LAUNCH_REJECTED The application cannot be launched in current context + * @retval #APP_CONTROL_ERROR_LAUNCH_FAILED Failed to launch the application + * @retval #APP_CONTROL_ERROR_TIMED_OUT Failed due to timeout. The application that handles @a app_control may be busy + * @retval #APP_CONTROL_ERROR_PERMISSION_DENIED Permission denied + * @post If the launch request is sent for the result, the result will come back through app_control_reply_cb() from the callee application. + * @see app_control_reply_to_launch_request() + * @see app_control_reply_cb() + */ +int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data); + + +/** + * @brief Sends the terminate request to the application that is launched by app_control. This API is only effective for some applications that are provided by default for handling platform default app_controls. You are not allowed to terminate other general applications using this API. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_PERMISSION_DENIED Permission denied + * @see app_control_send_launch_request() + */ +int app_control_send_terminate_request(app_control_h app_control); + + +/** + * @brief Replies to the launch request sent by the caller. + * @details If the caller application sent the launch request to receive the result, the callee application can return the result back to the caller. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] reply The app_control handle in which the results of the callee are contained + * @param[in] request The app_control handle sent by the caller + * @param[in] result The result code of the launch request + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_send_launch_request() + */ +int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result); + + +/** + * @brief Creates and returns a copy of the given app_control handle. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks A newly created app_control should be destroyed by calling app_control_destroy() if it is no longer needed. + * + * @param[out] clone If successful, a newly created app_control handle will be returned + * @param[in] app_control The app_control handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + * @see app_control_destroy() + */ +int app_control_clone(app_control_h *clone, app_control_h app_control); + + +/** + * @brief Gets the application ID of the caller from the launch request. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a app_control must be the launch request from app_control_cb(). + * @remarks This function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if the given app_control is not the launch request. + * @remarks The @a id must be released using free(). + * @param[in] app_control The app_control handle from app_control_cb() + * @param[out] id The application ID of the caller + * @return @a 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_control_get_caller(app_control_h app_control, char **id); + + +/** + * @brief Checks whether the caller is requesting a reply from the launch request. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a app_control must be the launch request from app_control_cb(). + * @remarks This function returns #APP_CONTROL_ERROR_INVALID_PARAMETER if the given app_control is not the launch request. + * @param[in] app_control The app_control handle from app_control_cb() + * @param[out] requested If @c true a reply is requested by the caller, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_CONTROL_ERROR_OUT_OF_MEMORY Out of memory + */ +int app_control_is_reply_requested(app_control_h app_control, bool *requested); + +/** + * @internal + * @brief Requests the specified callee window to be transient for the caller window. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a callee_id window is transient for the top-level caller window and should be handled accordingly. + * @param[in] app_control The app_control handle + * @param[in] callee_id The callee window ID + * @param[in] cbfunc The callback function to be called when the transient is requested + * @param[in] data A data pointer to pass to the callback function + * @return @c 0 on success, + * otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + */ +int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_APP_CONTROL_H__ */ diff --git a/include/app_control_internal.h b/include/app_control_internal.h new file mode 100644 index 0000000..3daa86b --- /dev/null +++ b/include/app_control_internal.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2014 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 __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ +#define __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file app_control_internal.h + */ + +/** + * @addtogroup CAPI_APP_CONTROL_MODULE + * @{ + */ + +/** + * @brief Replaces all data in the app_control with the bundle + * + * @remarks This function clears all data in the app_control and adds all key-value pairs in the bundle into the app_control + * @param [in] app_control The app_control handle + * @param [in] data The bundle handle + * @return 0 on success, otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_export_as_bundle() + * @code + * + * #include + * #include + * + * app_control_h app_control = NULL; + * app_control_create(&app_control); + * app_control_import_from_bundle(app_control, b); + * + * @endcode + * + */ +int app_control_import_from_bundle(app_control_h app_control, bundle *data); + +/** + * @brief Returns a new bundle containing all data contained int the app_control + * + * @remarks The @a data must be released with bundle_free() by you. + * @param [in] app_control The app_control handle + * @param [out] data The bundle handle + * @return 0 on success, otherwise a negative error value. + * @retval #APP_CONTROL_ERROR_NONE Successful + * @retval #APP_CONTROL_ERROR_INVALID_PARAMETER Invalid parameter + * @see app_control_import_from_bundle() + * @code + * + * #include + * #include + * + * bundle* b = NULL; + * app_control_export_as_bundle(app_control, &b); + * + * @endcode + */ +int app_control_export_as_bundle(app_control_h app_control, bundle **data); + +int app_control_create_request(bundle *data, app_control_h *app_control); + +int app_control_create_event(bundle *data, app_control_h *app_control); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_APP_CONTROL_INTERNAL_H__ */ diff --git a/include/app_i18n.h b/include/app_i18n.h index d6f1e81..69e0ce7 100755 --- a/include/app_i18n.h +++ b/include/app_i18n.h @@ -11,7 +11,7 @@ * 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. + * limitations under the License. */ @@ -25,26 +25,34 @@ extern "C" { #endif +/** + * @file app_i18n.h + */ + /** * @addtogroup CAPI_I18N_MODULE * @{ */ /** - * @brief Marks a string for translation, gets replaced with the translated string at runtime. - * @param [in] msg The string to be translated. + * @brief Definition to mark a string for translation, which is replaced with the translated string at runtime. + * @param[in] msg The string to be translated */ +#ifndef _ #define _(msg) i18n_get_text(msg) +#endif /** * @brief Gets the localized translation for the specified string. * - * @details If a translation was not found in the localization file(.po file), @a message is returned. + * @details If a translation is not found in the localization file(.po file), @a message is returned. * - * @remarks Do not free returned value + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks Do not free the returned value. * - * @param [in] message The string to be translated - * @return The localized translation for the given @a message on success, otherwise the given @a message. + * @param[in] message The string to be translated + * @return The localized translation for the given @a message on success, + * otherwise the given @a message */ char* i18n_get_text(const char *message); diff --git a/include/app_private.h b/include/app_internal.h similarity index 76% rename from include/app_private.h rename to include/app_internal.h index e949f8a..c42458e 100755 --- a/include/app_private.h +++ b/include/app_internal.h @@ -11,29 +11,23 @@ * 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. + * limitations under the License. */ -#ifndef __TIZEN_APPFW_APP_PRIVATE_H__ -#define __TIZEN_APPFW_APP_PRIVATE_H__ - -#include - -// GNU gettext macro is already defined at appcore-common.h -#ifdef _ -#undef _ -#endif - -#include +#ifndef __TIZEN_APPFW_APP_INTERNAL_H__ +#define __TIZEN_APPFW_APP_INTERNAL_H__ #ifdef __cplusplus extern "C" { #endif +#include +#include + #define TIZEN_PATH_MAX 1024 -#define PATH_FMT_APP_ROOT "/opt/apps" +#define PATH_FMT_APP_ROOT "/opt/usr/apps" #define PATH_FMT_RES_DIR PATH_FMT_APP_ROOT "/%s/res" #define PATH_FMT_LOCALE_DIR PATH_FMT_RES_DIR "/locale" #define PATH_FMT_DATA_DIR PATH_FMT_APP_ROOT "/%s/data" @@ -42,6 +36,19 @@ extern "C" { #define PATH_FMT_RO_RES_DIR PATH_FMT_RO_APP_ROOT "/%s/res" #define PATH_FMT_RO_LOCALE_DIR PATH_FMT_RO_RES_DIR "/locale" +struct app_event_handler { + app_event_type_e type; + app_event_cb cb; + void *data; +}; + +struct app_event_info { + app_event_type_e type; + void *value; +}; + +app_device_orientation_e app_convert_appcore_rm(enum appcore_rm rm); + typedef void (*app_finalizer_cb) (void *data); int app_error(app_error_e error, const char* function, const char *description); @@ -56,8 +63,10 @@ int app_finalizer_remove(app_finalizer_cb callback); void app_finalizer_execute(void); +int app_get_package(char **package); + #ifdef __cplusplus } #endif -#endif /* __TIZEN_APPFW_APP_PRIVATE_H__ */ +#endif /* __TIZEN_APPFW_APP_INTERNAL_H__ */ diff --git a/include/app_preference.h b/include/app_preference.h index 9aeb3af..8b2ff86 100755 --- a/include/app_preference.h +++ b/include/app_preference.h @@ -11,7 +11,7 @@ * 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. + * limitations under the License. */ @@ -25,32 +25,38 @@ extern "C" { #endif /** - * @addtogroup CAPI_PREFERENCE_MODULE + * @file app_preference.h + */ + +/** + * @addtogroup CAPI_PREFERENCE_MODULE * @{ */ /** - * @brief Enumerations of error code for Preference. + * @brief Enumeration for Preference Error. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { PREFERENCE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ PREFERENCE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ PREFERENCE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - PREFERENCE_ERROR_NO_KEY = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Required key not available */ + PREFERENCE_ERROR_NO_KEY = TIZEN_ERROR_APPLICATION | 0x30, /**< Required key not available */ PREFERENCE_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR , /**< Internal I/O Error */ } preference_error_e; /** - * @brief Called when the given key's value in the preference changes. + * @brief Called when the given key's value in the preference changes. * - * @details When the @a key is added or removed, this callback function is skipped. (only update can be handled) + * @details When the @a key is added or removed, this callback function is skipped(only update can be handled). * - * @param [in] key The name of the key in the preference - * @param [in] user_data The user data passed from the callback registration function - * @pre This function is invoked when the value of the key is overwritten after you register this callback using preference_set_changed_cb() + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key in the preference + * @param[in] user_data The user data passed from the callback registration function + * @pre This function is invoked when the value of the key is overwritten after you register this callback using preference_set_changed_cb(). * @see preference_set_changed_cb() * @see preference_unset_changed_cb() * @see preference_set_boolean() @@ -62,42 +68,47 @@ typedef void (*preference_changed_cb) (const char *key, void *user_data); /** -* @brief Called to get key string once for each key-value pair in the preference. -* -* @remarks You should not free @a key returned by this function. -* -* @param [in] key The key of the value added to the preference -* @param [in] value The value associated with the key -* @param [in] user_data The user data passed from the foreach function -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre preference_foreach_item() will invoke this callback function. -* @see preference_foreach_item() -*/ + * @brief Called to get key string, once for each key-value pair in the preference. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks You should not free the @a key returned by this function. + * + * @param[in] key The key of the value added to the preference + * @param[in] value The value associated with the key + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * @pre preference_foreach_item() will invoke this callback function. + * @see preference_foreach_item() + */ typedef bool (*preference_item_cb)(const char *key, void *user_data); /** * @brief Sets an integer value in the preference. * - * @param [in] key The name of the key to modify - * @param [in] value The new @c int value for the given key - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to modify + * @param[in] value The new @c int value for the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_get_int() - * */ int preference_set_int(const char *key, int value); /** - * @brief Gets a integer value from the preference. + * @brief Gets an integer value from the preference. * - * @param [in] key The name of the key to retrieve - * @param [out] value The @c int value for the given key - * @return 0 on success, otherwise a negative error value. - * @retval #PREFERENCE_ERROR_NONE Successful + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to retrieve + * @param[out] value The @c int value for the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_NO_KEY Required key not available * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error @@ -109,14 +120,15 @@ int preference_get_int(const char *key, int *value); /** * @brief Sets a double value in the preference. * - * @param [in] key The name of the key to modify - * @param [in] value The new @c double value associated with given key - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to modify + * @param[in] value The new @c double value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_get_double() - * */ int preference_set_double(const char *key, double value); @@ -124,15 +136,16 @@ int preference_set_double(const char *key, double value); /** * @brief Gets a double value from the preference. * - * @param [in] key The name of the key to retrieve - * @param [out] value The @c double value associated with given key - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to retrieve + * @param[out] value The @c double value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_NO_KEY Required key not available * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_set_double() - * */ int preference_get_double(const char *key, double *value); @@ -141,15 +154,16 @@ int preference_get_double(const char *key, double *value); * @brief Sets a string value in the preference. * * @details It makes a deep copy of the added string value. - * - * @param [in] key The name of the key to modify - * @param [in] value The new @c string value associated with given key - * @return 0 on success, otherwise a negative error value. + * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to modify + * @param[in] value The new @c string value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_get_string() - * */ int preference_set_string(const char *key, const char *value); @@ -157,11 +171,13 @@ int preference_set_string(const char *key, const char *value); /** * @brief Gets a string value from the preference. * - * @remarks @a value must be released with free() by you. - * @param [in] key The name of the key to retrieve - * @param [out] value The @c string value associated with given key - * @return 0 on success, otherwise a negative error value. - * @retval #PREFERENCE_ERROR_NONE Successful + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks @a value must be released using free(). + * @param[in] key The name of the key to retrieve + * @param[out] value The @c string value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_OUT_OF_MEMORY Out of memory * @retval #PREFERENCE_ERROR_NO_KEY Required key not available @@ -174,12 +190,14 @@ int preference_get_string(const char *key, char **value); /** * @brief Sets a boolean value in the preference. * - * @param [in] key The name of the key to modify - * @param [in] value The new boolean @c value associated with given key - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to modify + * @param[in] value The new @c boolean value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error + * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_get_boolean() */ int preference_set_boolean(const char *key, bool value); @@ -188,9 +206,11 @@ int preference_set_boolean(const char *key, bool value); /** * @brief Gets a boolean value from the preference. * - * @param [in] key The name of the key to retrieve - * @param [out] value The boolean @c value associated with given key - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to retrieve + * @param[out] value The @c boolean value associated with the given key + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_NO_KEY Required key not available @@ -203,22 +223,26 @@ int preference_get_boolean(const char *key, bool *value); /** * @brief Removes any value with the given @a key from the preference. * - * @param [in] key The name of the key to remove - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to remove + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful - * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error - * */ int preference_remove(const char *key); /** - * @brief Checks whether if the given @a key exists in the preference. + * @brief Checks whether the given @a key exists in the preference. * - * @param [in] key The name of the key to check - * @param [out] existing @c true if the @a key exists in the preference, otherwise @c false - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to check + * @param[out] existing If @c true the @a key exists in the preference, + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error @@ -229,7 +253,9 @@ int preference_is_existing(const char *key, bool *existing); /** * @brief Removes all key-value pairs from the preference. * - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error * @see preference_remove() @@ -240,10 +266,12 @@ int preference_remove_all(void); /** * @brief Registers a callback function to be invoked when value of the given key in the preference changes. * - * @param [in] key The name of the key to monitor - * @param [in] callback The callback function to register - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to monitor + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_OUT_OF_MEMORY Out of memory @@ -259,8 +287,10 @@ int preference_set_changed_cb(const char *key, preference_changed_cb callback, v /** * @brief Unregisters the callback function. * - * @param [in] key The name of the key to monitor - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] key The name of the key to monitor + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error @@ -272,9 +302,11 @@ int preference_unset_changed_cb(const char *key); /** * @brief Retrieves all key-value pairs in the preference by invoking the callback function. * - * @param [in] callback The callback function to get key value once for each key-value pair in the preference - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] callback The callback function to get key value once for each key-value pair in the preference + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value * @retval #PREFERENCE_ERROR_NONE Successful * @retval #PREFERENCE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #PREFERENCE_ERROR_IO_ERROR Internal I/O Error diff --git a/include/app_preference_internal.h b/include/app_preference_internal.h new file mode 100755 index 0000000..1d43bc2 --- /dev/null +++ b/include/app_preference_internal.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_APPFW_PREFERENCE_INTERNAL_H__ +#define __TIZEN_APPFW_PREFERENCE_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_preference_log.h" +#include "linux/limits.h" + +#define BUF_LEN (4096) +#define PREF_DIR ".pref/" + +#define PREFERENCE_KEY_PATH_LEN 1024 +#define ERR_LEN 128 + +#define PREF_DB_NAME ".pref.db" +#define PREF_TBL_NAME "pref" +#define PREF_F_KEY_NAME "pref_key" +#define PREF_F_TYPE_NAME "pref_type" +#define PREF_F_DATA_NAME "pref_data" + +/* ASCII VALUE */ +#define PREF_KEYNAME_C_PAD '=' +#define PREF_KEYNAME_C_PLUS '+' +#define PREF_KEYNAME_C_SLASH '/' + +#define PREF_KEYNAME_C_DOT '.' +#define PREF_KEYNAME_C_UNDERSCORE '_' +#define PREF_KEYNAME_C_HYPHEN '-' + +/** + * @brief Definition for PREFERENCE_ERROR_WRONG_PREFIX. + */ +#define PREFERENCE_ERROR_WRONG_PREFIX -2 + +/** + * @brief Definition for PREFERENCE_ERROR_WRONG_TYPE. + */ +#define PREFERENCE_ERROR_WRONG_TYPE -3 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_OPEN. + */ +#define PREFERENCE_ERROR_FILE_OPEN -21 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_FREAD. + */ +#define PREFERENCE_ERROR_FILE_FREAD -22 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_FGETS. + */ +#define PREFERENCE_ERROR_FILE_FGETS -23 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_WRITE. + */ +#define PREFERENCE_ERROR_FILE_WRITE -24 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_SYNC. + */ +#define PREFERENCE_ERROR_FILE_SYNC -25 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_CHMOD. + */ +#define PREFERENCE_ERROR_FILE_CHMOD -28 + +/** + * @brief Definition for PREFERENCE_ERROR_FILE_LOCK. + */ +#define PREFERENCE_ERROR_FILE_LOCK -29 + +typedef enum +{ + PREFERENCE_TYPE_NONE = 0, + PREFERENCE_TYPE_STRING, + PREFERENCE_TYPE_INT, + PREFERENCE_TYPE_DOUBLE, + PREFERENCE_TYPE_BOOLEAN, +} preference_type_e; + +typedef struct _pref_changed_cb_node_t{ + char *key; + preference_changed_cb cb; + void *user_data; + struct _pref_changed_cb_node_t *prev; + struct _pref_changed_cb_node_t *next; +} pref_changed_cb_node_t; + +typedef struct _keynode_t { + char *keyname; /**< Keyname for keynode */ + int type; /**< Keynode type */ + union { + int i; /**< Integer type */ + int b; /**< Bool type */ + double d; /**< Double type */ + char *s; /**< String type */ + } value; /**< Value for keynode */ + struct _keynode_t *next; /**< Next keynode */ +} keynode_t; + +/** + * @brief The structure type for opaque type. It must be used via accessor functions. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ +typedef struct _keylist_t { + int num; /**< Number of list */ + keynode_t *head; /**< Head node */ + keynode_t *cursor; /**< Cursor node */ +} keylist_t; + + +int _preference_kdb_add_notify + (keynode_t *keynode, preference_changed_cb cb, void *data); +int _preference_kdb_del_notify + (keynode_t *keynode); + +int _preference_get_key_path(keynode_t *keynode, char *path); +int _preference_get_key(keynode_t *keynode); + +int _preference_keynode_set_keyname(keynode_t *keynode, const char *keyname); +inline void _preference_keynode_set_null(keynode_t *keynode); +inline keynode_t *_preference_keynode_new(void); +inline void _preference_keynode_free(keynode_t *keynode); + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_APPFW_PREFERENCE_INTERNAL_H__ */ diff --git a/include/app_preference_log.h b/include/app_preference_log.h new file mode 100755 index 0000000..8bd87a7 --- /dev/null +++ b/include/app_preference_log.h @@ -0,0 +1,92 @@ +/* + * 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. + */ + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "CAPI_APPFW_APPLICATION_PREFERENCE" +#define DBG_MODE (1) + +#ifndef __PREFERENCE_LOG_H__ +#define __PREFERENCE_LOG_H__ + +#include +#include +#include +#include + + +#define INFO(fmt, arg...) +#define DBG(fmt, arg...) SECURE_SLOGI(fmt, ##arg) +#define ERR(fmt, arg...) LOGE(fmt, ##arg) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) +#define FATAL(fmt, arg...) SECURE_SLOGF(fmt, ##arg) +#define WARN(fmt, arg...) SECURE_SLOGW(fmt, ##arg) + + +/************** Return ***************/ +#define ret_if(expr) \ + do { \ + if (expr) { \ + ERR("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ + } while (0) +#define retv_if(expr, val) \ + do { \ + if (expr) { \ + ERR("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ + } while (0) +#define retm_if(expr, fmt, arg...) \ + do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + } \ + } while (0) +#define retvm_if(expr, val, fmt, arg...) \ + do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while (0) +#define retex_if(expr, fmt, arg...) \ + do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + goto CATCH; \ + } \ + } while (0) + + +/************** TimeCheck ***************/ +#ifdef PREFERENCE_TIMECHECK +#define START_TIME_CHECK \ + init_time();\ + startT = set_start_time(); +#define END_TIME_CHECK \ + PREFERENCE_DEBUG("time = %f ms\n", exec_time(startT)); +#else +#define START_TIME_CHECK +#define END_TIME_CHECK +#endif + + +#endif /* __PREFERENCE_LOG_H__ */ diff --git a/include/app_preference_private.h b/include/app_preference_private.h deleted file mode 100755 index aaf4a87..0000000 --- a/include/app_preference_private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_APPFW_PREFERENCE_PRIVATE_H__ -#define __TIZEN_APPFW_PREFERENCE_PRIVATE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define PREF_DB_NAME ".pref.db" -#define PREF_TBL_NAME "pref" -#define PREF_F_KEY_NAME "pref_key" -#define PREF_F_TYPE_NAME "pref_type" -#define PREF_F_DATA_NAME "pref_data" -#define BUF_LEN (4096) - -typedef enum -{ - PREFERENCE_TYPE_INT = 1, - PREFERENCE_TYPE_BOOLEAN, - PREFERENCE_TYPE_DOUBLE, - PREFERENCE_TYPE_STRING -} preference_type_e; - -typedef struct _pref_changed_cb_node_t{ - char *key; - preference_changed_cb cb; - void *user_data; - struct _pref_changed_cb_node_t *prev; - struct _pref_changed_cb_node_t *next; -} pref_changed_cb_node_t; - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_PREFERENCE_PRIVATE_H__ */ diff --git a/include/app_service.h b/include/app_service.h deleted file mode 100755 index ee71d33..0000000 --- a/include/app_service.h +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_APPFW_SERVICE_H__ -#define __TIZEN_APPFW_SERVICE_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @addtogroup CAPI_SERVICE_MODULE - * @{ - */ - - -/** - * @brief Service handle. - */ -typedef struct service_s *service_h; - - -/** - * @brief Enumerations of error code for Service. - */ -typedef enum -{ - SERVICE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - SERVICE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - SERVICE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - SERVICE_ERROR_APP_NOT_FOUND = TIZEN_ERROR_APPLICATION_CLASS | 0x21, /**< The application was not found */ - SERVICE_ERROR_KEY_NOT_FOUND = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Specified key not found */ - SERVICE_ERROR_KEY_REJECTED = TIZEN_ERROR_KEY_REJECTED, /**< Not available key */ - SERVICE_ERROR_INVALID_DATA_TYPE = TIZEN_ERROR_APPLICATION_CLASS | 0x22, /**< Invalid data type */ -} service_error_e; - - -/** - * @brief Enumeration of service result. - */ -typedef enum -{ - SERVICE_RESULT_SUCCEEDED = 0, /**< Operation succeeded */ - SERVICE_RESULT_FAILED = -1, /**< Operation failed by the callee */ - SERVICE_RESULT_CANCELED = -2, /**< Operation canceled by the framework */ -} service_result_e; - - -/** - * @brief Service operation : default operation for explicit launch - */ -#define SERVICE_OPERATION_DEFAULT "http://tizen.org/appcontrol/operation/default" - - -/** - * @brief Service operation : provide explicit editable access to the given data. - */ -#define SERVICE_OPERATION_EDIT "http://tizen.org/appcontrol/operation/edit" - - -/** - * @brief Service operation : display the data. - */ -#define SERVICE_OPERATION_VIEW "http://tizen.org/appcontrol/operation/view" - - -/** - * @brief Service operation : pick an item from the data, returning what was selected. - */ -#define SERVICE_OPERATION_PICK "http://tizen.org/appcontrol/operation/pick" - - -/** - * @brief Service operation : create a content, returning what was created. - */ -#define SERVICE_OPERATION_CREATE_CONTENT "http://tizen.org/appcontrol/operation/create_content" - - -/** - * @brief Service operation : perform a call to someone specified by the data. - */ -#define SERVICE_OPERATION_CALL "http://tizen.org/appcontrol/operation/call" - - -/** - * @brief Service operation : deliver some data to someone else. - */ -#define SERVICE_OPERATION_SEND "http://tizen.org/appcontrol/operation/send" - - -/** - * @brief Service operation : deliver text data to someone else. - */ -#define SERVICE_OPERATION_SEND_TEXT "http://tizen.org/appcontrol/operation/send_text" - - -/** - * @brief Service operation : dial a number as specified by the data. - */ -#define SERVICE_OPERATION_DIAL "http://tizen.org/appcontrol/operation/dial" - - -/** - * @brief Service operation : perform a search. - */ -#define SERVICE_OPERATION_SEARCH "http://tizen.org/appcontrol/operation/search" - - -/** - * @brief Service optional data : the subject of a message. - */ -#define SERVICE_DATA_SUBJECT "http://tizen.org/appcontrol/data/subject" - - -/** - * @brief Service optional data : e-mail addresses. - */ -#define SERVICE_DATA_TO "http://tizen.org/appcontrol/data/to" - - -/** - * @brief Service optional data : e-mail addresses that should be carbon copied. - */ -#define SERVICE_DATA_CC "http://tizen.org/appcontrol/data/cc" - - -/** - * @brief Service optional data : e-mail addresses that should be blind carbon copied. - */ -#define SERVICE_DATA_BCC "http://tizen.org/appcontrol/data/bcc" - - -/** - * @brief Service optional data : the content of the data is associated with #SERVICE_OPERATION_SEND. - */ -#define SERVICE_DATA_TEXT "http://tizen.org/appcontrol/data/text" - - -/** - * @brief Service optional data : the title of the data - */ -#define SERVICE_DATA_TITLE "http://tizen.org/appcontrol/data/title" - - -/** - * @brief Service optional data : the path of selected item. - */ -#define SERVICE_DATA_SELECTED "http://tizen.org/appcontrol/data/selected" - - -/** - * @brief Called when the reply of the launch request is delivered. - * - * @remarks The @a request and @a reply must not be deallocated by an application. - * - * @param [in] request The service handle of the launch request that has sent - * @param [in] reply The service handle in which the results of the callee are contained - * @param [in] result The result code of the launch request - * @param [in] user_data The user data passed from the callback registration function - * @pre When the callee replies to the launch request, this callback will be invoked. - * @see service_send_launch_request() - * @see service_reply_to_launch_request() - */ -typedef void (*service_reply_cb) (service_h request, service_h reply, service_result_e result, void *user_data); - - -/** -* @brief Called to retrieve the extra data that are contained in the service -* -* @remarks The @a key must not be deallocated by an application. -* -* @param[in] service The service handle -* @param[in] key The key of the value contained in the service -* @param[in] user_data The user data passed from the foreach function -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre service_foreach_extra_data() will invoke this callback. -* @see service_foreach_extra_data() -*/ -typedef bool (*service_extra_data_cb)(service_h service, const char *key, void *user_data); - - -/** -* @brief Called once for each matched application that can be launched to handle the given service request. -* -* @param [in] service The service handle -* @param [in] package The package name of the application that can handle the launch request of the given service. -* @param [in] user_data The user data passed from the foreach function -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre service_foreach_app_matched() will invoke this callback. -* @see service_foreach_app_matched() -*/ -typedef bool (*service_app_matched_cb)(service_h service, const char *package, void *user_data); - - -/** - * @brief Creates a service handle. - * - * @remarks The @a service must be released with service_destroy() by you. - * @param [out] service A service handle to be newly created on success - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_destroy() - */ -int service_create(service_h *service); - - -/** - * @brief Destroys the service handle and releases all its resources. - * - * @param [in] service The service handle - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_create() - */ -int service_destroy(service_h service); - - -/** - * @brief Sets the operation to be performed. - * - * @details The @a operation is the mandatory information for the launch request. - * If the operation is not specified, #SERVICE_OPERATION_DEFAULT is used for the launch request. - * If the operation is #SERVICE_OPERATION_DEFAULT, the package information is mandatory to explicitly launch the application - * @param [in] service The service handle - * @param [in] operation The operation to be performed \n - * If the @a operation is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @see service_get_operation() - * @see SERVICE_OPERATION_DEFAULT - * @see SERVICE_OPERATION_EDIT - * @see SERVICE_OPERATION_VIEW - * @see SERVICE_OPERATION_PICK - * @see SERVICE_OPERATION_CREATE_CONTENT - * @see SERVICE_OPERATION_CALL - * @see SERVICE_OPERATION_SEND - * @see SERVICE_OPERATION_SEND_TEXT - * @see SERVICE_OPERATION_DIAL - * @see SERVICE_OPERATION_SEARCH - */ -int service_set_operation(service_h service, const char *operation); - - -/** - * @brief Gets the operation to be performed. - * - * @remarks The @a operation must be released with free() by you. - * @param [in] service The service handle - * @param [out] operation The operation to be performed - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_set_operation() - */ -int service_get_operation(service_h service, char **operation); - - -/** - * @brief Sets the URI of the data. - * - * @param [in] service The service handle - * @param [in] uri The URI of the data this service is operating on \n - * If the @a uri is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @see service_get_uri() - */ -int service_set_uri(service_h service, const char *uri); - - -/** - * @brief Gets the URI of the data. - * - * @remarks The @a uri must be released with free() by you. - * @param [in] service The service handle - * @param [out] uri The URI of the data this service is operating on - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_set_uri() - */ -int service_get_uri(service_h service, char **uri); - - -/** - * @brief Sets the explicit MIME type of the data - * - * @param [in] service The service handle - * @param [in] mime the explicit MIME type of the data this service is operating on \n - * If the @a mime is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @see service_get_mime() - */ -int service_set_mime(service_h service, const char *mime); - - -/** - * @brief Gets the explicit MIME type of the data. - * - * @remarks The @a uri must be released with free() by you. - * @param [in] service The service handle - * @param [out] mime The explicit MIME type of the data this service is operating on - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_set_mime() - */ -int service_get_mime(service_h service, char **mime); - - -/** - * @brief Sets the package name of the application to explicitly launch - * - * @remark This function is @b deprecated. Use service_set_app_id() instead. - * @param [in] service The service handle - * @param [in] package The package name of the application to explicitly launch \n - * If the @a package is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_get_package() - */ -int service_set_package(service_h service, const char *package); - - -/** - * @brief Gets the package name of the application to explicitly launch - * - * @remark This function is @b deprecated. Use service_get_app_id() instead. - * @remarks The @a package must be released with free() by you. - * @param [in] service The service handle - * @param [out] package The package name of the application to explicitly launch - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_set_package() - */ -int service_get_package(service_h service, char **package); - - -/** - * @brief Sets the ID of the application to explicitly launch - * - * @param [in] service The service handle - * @param [in] app_id The ID of the application to explicitly launch \n - * If the @a app_id is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_get_app_id() - */ -int service_set_app_id(service_h service, const char *app_id); - - -/** - * @brief Gets the ID of the application to explicitly launch - * - * @remarks The @a app_id must be released with free() by you. - * @param [in] service The service handle - * @param [out] app_id The ID of the application to explicitly launch - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_set_app_id() - */ -int service_get_app_id(service_h service, char **app_id); - -/** - * @brief Sets the window id of the application - * - * @param [in] service The service handle - * @param [in] id the window id of caller application \n - * If the @a id is not positive, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_get_window() - */ -int service_set_window(service_h service, unsigned int id); - - -/** -* @brief Gets the window id of the application -* -* @param [in] service The service handle -* @param [out] id The window id of caller application -* @return 0 on success, otherwise a negative error value. -* @retval #SERVICE_ERROR_NONE Successful -* @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory -* @see service_set_package() -*/ -int service_get_window(service_h service, unsigned int *id); - - -/** - * @brief Adds the extra data to the service. - * - * @remarks The function replaces any existing value for the given key. - * @remarks The function returns #SERVICE_ERROR_INVALID_PARAMETER if key or value is zero-length string. - * @remarks The function returns #SERVICE_ERROR_KEY_REJECTED if the application tries to use same key with system-defined key - * @param [in] service The service handle - * @param [in] key The name of the extra data - * @param [in] value The value associated with given key - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_KEY_REJECTED Not available key - * @see service_add_extra_data_array() - * @see service_remove_extra_data() - * @see service_get_extra_data() - */ -int service_add_extra_data(service_h service, const char *key, const char *value); - - -/** - * @brief Adds the extra data array to the service. - * - * @remarks The function replaces any existing value for the given key. - * @remarks The function returns #SERVICE_ERROR_INVALID_PARAMETER if key is zero-length string. - * @remarks The function returns #SERVICE_ERROR_KEY_REJECTED if the application tries to use same key with system-defined key - * @param [in] service The service handle - * @param [in] key The name of the extra data - * @param [in] value The array value associated with given key - * @param [in] length The length of the array - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_KEY_REJECTED Not available key - * @see service_add_extra_data() - * @see service_remove_extra_data() - * @see service_get_extra_data() - */ -int service_add_extra_data_array(service_h service, const char *key, const char* value[], int length); - - -/** - * @brief Removes the extra data from the service. - * - * @param [in] service The service handle - * @param [in] key The name of the extra data - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_KEY_NOT_FOUND Specified key not found - * @see service_add_extra_data() - * @see service_add_extra_data_array() - * @see service_get_extra_data() - */ -int service_remove_extra_data(service_h service, const char *key); - - -/** - * @brief Gets the extra data from the service. - * - * @remarks The @a value must be released with free() by you. - * @remarks The function returns #SERVICE_ERROR_INVALID_DATA_TYPE if the value is array data type. - * @param [in] service The service handle - * @param [int] key The name of the extra data - * @param [out] value The value associated with given key - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_KEY_NOT_FOUND Specified key not found - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @retval #SERVICE_ERROR_INVALID_DATA_TYPE Invalid data type - * @see service_add_extra_data() - * @see service_add_extra_data_array() - * @see service_get_extra_data() - * @see service_remove_extra_data() - * @see service_foreach_extra_data() - */ -int service_get_extra_data(service_h service, const char *key, char **value); - - -/** - * @brief Gets the extra data array from the service. - * - * @remarks The @a value must be released with free() by you. - * @remarks The function returns #SERVICE_ERROR_INVALID_DATA_TYPE if the value is not array data type. - * @param [in] service The service handle - * @param [int] key The name of the extra data - * @param [out] value The array value associated with given key - * @param [out] length The length of the array - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_KEY_NOT_FOUND Specified key not found - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @retval #SERVICE_ERROR_INVALID_DATA_TYPE Invalid data type - * @see service_add_extra_data() - * @see service_add_extra_data_array() - * @see service_remove_extra_data() - * @see service_foreach_extra_data() - */ -int service_get_extra_data_array(service_h service, const char *key, char ***value, int *length); - - -/** - * @brief Checks whether if the extra data associated with given @a key is array data type. - * - * @param [in] service The service handle - * @param [int] key The name of the extra data - * @param [out] array @c True if the extra data is array data type, otherwise @c false - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @see service_add_extra_data() - * @see service_add_extra_data_array() - * @see service_remove_extra_data() - * @see service_foreach_extra_data() - */ -int service_is_extra_data_array(service_h service, const char *key, bool *array); - - -/** - * @brief Retrieves all extra data contained in service. - * @details This function calls service_extra_data_cb() once for each key-value pair for extra data contained in service. \n - * If service_extra_data_cb() callback function returns false, then iteration will be finished. - * - * @param [in] service The service handle - * @param [in] callback The iteration callback function - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @post This function invokes service_extra_data_cb(). - * @see service_extra_data_cb() - */ -int service_foreach_extra_data(service_h service, service_extra_data_cb callback, void *user_data); - - -/** - * @brief Retrieves all applications that can be launched to handle the given service request. - * - * @param [in] service The service handle - * @param [in] callback The iteration callback function - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Success - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @post This function invokes service_app_matched_cb(). - * @see service_app_matched_cb() - */ -int service_foreach_app_matched(service_h service, service_app_matched_cb callback, void *user_data); - - -/** - * @brief Sends the launch request. - * - * @details The operation is mandatory information for the launch request. \n - * If the operation is not specified, #SERVICE_OPERATION_DEFAULT is used by default. - * If the operation is #SERVICE_OPERATION_DEFAULT, the application ID is mandatory to explicitly launch the application - * @param [in] service The service handle - * @param [in] callback The callback function to be called when the reply is delivered - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @retval #SERVICE_ERROR_APP_NOT_FOUND The application was not found to run the given launch request - * @post If the launch request is sent for the result, the result will come back through service_reply_cb() from the callee application - * @see service_reply_to_launch_request() - * @see service_reply_cb() - */ -int service_send_launch_request(service_h service, service_reply_cb callback, void *user_data); - - -/** - * @brief Replies to the launch request that the caller sent - * @details If the caller application sent the launch request to receive the result, the callee application can return the result back to the caller. - * - * @param [in] reply The service handle in which the results of the callee are contained - * @param [in] request The service handle that the caller sent - * @param [in] result The result code of the launch request - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_send_launch_request() - */ -int service_reply_to_launch_request(service_h reply, service_h request, service_result_e result); - - -/** - * @brief Creates and returns a copy of the given service handle. - * - * @remarks A newly created service should be destroyed by calling service_destroy() if it is no longer needed. - * - * @param [out] clone If successful, a newly created service handle will be returned. - * @param [in] service The service handle - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - * @see service_destroy() - */ -int service_clone(service_h *clone, service_h service); - - -/** - * @brief Gets the application ID of the caller from the launch request - * - * @remarks The @a service must be the launch reqeust from app_service_cb(). - * @remarks This function returns #SERVICE_ERROR_INVALID_PARAMETER if the given service is not the launch request. - * @remarks The @a id must be released with free() by you. - * @param [in] service The service handle from app_service_cb() - * @param [out] id The application ID of the caller - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - */ -int service_get_caller(service_h service, char **id); - - -/** - * @brief Check whether the caller is requesting a reply from the launch reqeust - * - * @remarks The @a service must be the launch reqeust from app_service_cb(). - * @remarks This function returns #SERVICE_ERROR_INVALID_PARAMETER if the given service is not the launch request. - * @param [in] service The service handle from app_service_cb() - * @param [out] requested whether a reply is requested by the caller - * @return 0 on success, otherwise a negative error value. - * @retval #SERVICE_ERROR_NONE Successful - * @retval #SERVICE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #SERVICE_ERROR_OUT_OF_MEMORY Out of memory - */ -int service_is_reply_requested(service_h service, bool *requested); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_SERVICE_H__ */ diff --git a/include/app_service_private.h b/include/app_service_private.h deleted file mode 100755 index 6f71533..0000000 --- a/include/app_service_private.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_APPFW_SERVICE_PRIVATE_H__ -#define __TIZEN_APPFW_SERVICE_PRIVATE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int service_create_request(bundle *data, service_h *service); - -int service_create_event(bundle *data, service_h *service); - -int service_to_bundle(service_h service, bundle **data); - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_SERVICE_PRIVATE_H__ */ diff --git a/include/app_storage.h b/include/app_storage.h deleted file mode 100644 index 0afe823..0000000 --- a/include/app_storage.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __TIZEN_APPFW_STORAGE_H__ -#define __TIZEN_APPFW_STORAGE_H__ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /** - * @addtogroup CAPI_STORAGE_MODULE - * @{ - */ - - -/** - * @brief Enumerations of error code for Storage. - */ -typedef enum -{ - STORAGE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - STORAGE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - STORAGE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - STORAGE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NO_SUCH_DEVICE /**< Not supported storage */ -} storage_error_e; - - -/** - * @brief Enumerations of the storage type. - */ -typedef enum -{ - STORAGE_TYPE_INTERNAL, /**< Internal device storage (built-in storage in a device, non-removable) */ - STORAGE_TYPE_EXTERNAL, /**< External storage */ -} storage_type_e; - - -/** - * @brief Enumerations of the state of storage device. - */ -typedef enum -{ - STORAGE_STATE_UNMOUNTABLE = -2, /**< Storage is present but cannot be mounted. Typically it happens if the file system of the storage is corrupted. */ - STORAGE_STATE_REMOVED = -1, /**< Storage is not present. */ - STORAGE_STATE_MOUNTED = 0, /**< Storage is present and mounted with read/write access. */ - STORAGE_STATE_MOUNTED_READ_ONLY = 1, /**< Storage is present and mounted with read only access. */ -} storage_state_e; - - -/** -* @brief Called to get information once for each supported storage. -* -* @param [in] storage The unique storage ID -* @param [in] type The type of the storage -* @param [in] state The current state of the storage -* @param [in] path The absolute path to the root directory of the @a storage -* @param [in] user_data The user data passed from the foreach function -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre storage_foreach_device_supported() will invoke this callback function. -* @see storage_foreach_device_supported() -*/ -typedef bool (*storage_device_supported_cb)(int storage, storage_type_e type, storage_state_e state, const char *path, void *user_data); - - -/** -* @brief Called when the state of storage changes -* -* @param [in] storage The unique storage ID -* @param [in] state The current state of the storage -* @param [in] user_data The user data passed from the foreach function -* @pre storage_set_state_changed_cb() will invoke this callback function. -* @see storage_set_state_changed_cb() -* @see storage_unset_state_changed_cb() -*/ -typedef void (*storage_state_changed_cb)(int storage, storage_state_e state, void *user_data); - - -/** - * @brief Retrieves all storage in device. - * @details This function invokes the callback function once for each @a storage in device. \n - * If storage_device_supported_cb() returns @c false, then iteration will be finished. - * - * @param [in] callback The iteration callback function - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @post This function invokes storage_device_supported_cb() repeatedly for each supported device. - * @see storage_device_supported_cb() - */ -int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data); - - -/** - * @brief Gets the absolute path to the root directory of the given @a storage. - * @details - * Files saved on the internal/external storage are readable or writeable by all applications. - * When an application is uninstalled, the files written by that application are not removed from the internal/external storage. - * - * @remarks @a path must be released with free() by you. - * - * @param[in] storage The storage device - * @param[out] path The absolute path to the storage directory - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - * @see storage_get_state() - */ -int storage_get_root_directory(int storage, char **path); - - -/** - * @brief Gets the type of the given @a storage. - * - * @param[in] storage The storage device - * @param[out] type The type of the storage - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - */ -int storage_get_type(int storage, storage_type_e *type); - - -/** - * @brief Gets the current state of the given @a storage. - * - * @param[in] storage The storage device - * @param[out] state The current state of the storage, - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - * @see storage_get_root_directory() - * @see storage_get_total_space() - * @see storage_get_available_space() - */ -int storage_get_state(int storage, storage_state_e *state); - - -/** - * @brief Registers a callback function to be invoked when the state of the storage changes. - * - * @param[in] storage The storage device - * @param[in] callback The callback function to register - * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - * @post storage_state_changed_cb() will be invoked if the state of registered storage changes. - * @see storage_state_changed_cb() - * @see storage_unset_state_changed_cb() - */ -int storage_set_state_changed_cb(int storage, storage_state_changed_cb callback, void *user_data); - - -/** - * @brief Unregisters the callback function. - * - * @param [in] storage The storage device to monitor - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - * @see storage_state_changed_cb() - * @see storage_set_state_changed_cb() - */ -int storage_unset_state_changed_cb(int storage); - -/** - * @brief Gets the total space of the given @a storage in bytes. - * - * @param[in] storage The storage device - * @param[out] bytes The total space size of the storage (bytes) - * @return 0 on success, otherwise a negative error value - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - * @see storage_get_state() - * @see storage_get_available_space() - */ -int storage_get_total_space(int storage, unsigned long long *bytes); - -/** - * @brief Gets the available space size of the given @a storage in bytes. - * - * @param[in] storage The storage device - * @param[out] bytes The available space size of the storage (bytes) - * @return 0 on success, otherwise a negative error value. - * @retval #STORAGE_ERROR_NONE Successful - * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #STORAGE_ERROR_NOT_SUPPORTED Not supported storage - - * @see storage_get_state() - * @see storage_get_total_space() - */ -int storage_get_available_space(int storage, unsigned long long *bytes); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_STORAGE_H__ */ diff --git a/include/app_storage_private.h b/include/app_storage_private.h deleted file mode 100755 index e5bf36c..0000000 --- a/include/app_storage_private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_APPFW_STORAGE_PRIVATE_H__ -#define __TIZEN_APPFW_STORAGE_PRIVATE_H__ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef int (*storage_dev_get_state)(void); -typedef int (*storage_dev_set_state_cb)(void *data); -typedef void (*storage_dev_unset_state_cb)(void); -typedef int (*storage_dev_get_space)(unsigned long long *total, unsigned long long *available); - -typedef struct storage_device_s -{ - storage_type_e type; - char *path; - storage_dev_get_state get_state; - storage_dev_set_state_cb set_state_cb; - storage_dev_unset_state_cb unset_state_cb; - storage_dev_get_space get_space; -} *storage_device_h; - -typedef struct storage_info_s -{ - int id; - storage_device_h device; - storage_state_e state; - storage_state_changed_cb state_cb; - void *state_cb_data; -} *storage_info_h; - -void storage_dispatch_state_event(storage_state_e state, void* data); - -int storage_statfs(const char *directory, unsigned long long *total, unsigned long long *available); - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_STORAGE_PRIVATE_H__ */ diff --git a/include/app_types.h b/include/app_types.h new file mode 100644 index 0000000..80c19d0 --- /dev/null +++ b/include/app_types.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + + +#ifndef __TIZEN_APPFW_APP_TYPES_H__ +#define __TIZEN_APPFW_APP_TYPES_H__ + +#include + +/** + * @file app_types.h + */ + +/** + * @addtogroup CAPI_APPLICATION_MODULE + * @{ + */ + +/** + * @brief Enumeration for application error. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + */ + +typedef enum +{ + APP_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + APP_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + APP_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + APP_ERROR_INVALID_CONTEXT = TIZEN_ERROR_APPLICATION | 0x01, /**< Invalid application context */ + APP_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file or directory */ + APP_ERROR_ALREADY_RUNNING = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Application is already running */ + APP_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied @if MOBILE (Since 2.3.1) @endif */ +} app_error_e; + +/** + * @} + */ + +#endif /* __TIZEN_APPFW_APP_TYPES_H__ */ diff --git a/include/app_ui_notification.h b/include/app_ui_notification.h deleted file mode 100755 index ba17898..0000000 --- a/include/app_ui_notification.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_APPFW_UI_NOTIFICATION_H__ -#define __TIZEN_APPFW_UI_NOTIFICATION_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /** - * @addtogroup CAPI_UI_NOTIFICATION_MODULE - * @{ - */ - -/** - * @brief Notification handle. - */ -typedef struct ui_notification_s *ui_notification_h; - -/** - * @brief Enumerations of error code for notification. - */ -typedef enum { - UI_NOTIFICATION_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - UI_NOTIFICATION_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - UI_NOTIFICATION_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - UI_NOTIFICATION_ERROR_DB_FAILED = TIZEN_ERROR_APPLICATION_CLASS | 0x31, /**< DB operation failed */ - UI_NOTIFICATION_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file */ - UI_NOTIFICATION_ERROR_INVALID_STATE = TIZEN_ERROR_APPLICATION_CLASS | 0x32, /**< Invalid state */ -} ui_notification_error_e; - -/** - * @brief Enumeration of progress type for ongoing notification - */ -typedef enum { - UI_NOTIFICATION_PROGRESS_TYPE_SIZE, /**< Size in bytes */ - UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE, /**< Percentage (between 0.0 and 1.0) */ -} ui_notification_progress_type_e; - -/** -* @brief Called to retrieve the notifications posted. -* @remarks You should not free @a notification returned by this function. -* @param[in] notification The notification handle -* @param[in] user_data The user data passed from the foreach function -* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop. -* @pre ui_notification_foreach_notification_posted() will invoke this callback. -* @see ui_notification_foreach_notification_posted() -* @see ui_notification_clone() -*/ -typedef bool (*ui_notification_cb)(ui_notification_h notification, void *user_data); - -/** - * @brief Creates a notification handle. - * @remarks The @a notification must be released with ui_notification_destroy() by you. - * @param[in] ongoing A boolean value that sets whether this is an ongoing notification. - * @param[out] notification A UI notification handle to be newly created on success - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_destroy() - */ -int ui_notification_create(bool ongoing, ui_notification_h *notification); - -/** - * @brief Destroys the notification handle and releases all its resources. - * @param[in] notification The notification handle - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @see ui_notification_create() - */ -int ui_notification_destroy(ui_notification_h notification); - -/** - * @brief Checks whether the notification is ongoing or not - * @param[in] notification The notification handle - * @param[out] ongoing A boolean value that sets whether this is an ongoing notification. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @see ui_notification_create() - */ -int ui_notification_is_ongoing(ui_notification_h notification, bool *ongoing); - -/** - * @brief Sets the full path of the icon image to display in the notification. - * @remarks The @a path should be the absolute path. If the icon is not set, the icon of the application will be displayed. \n - * This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] path The absolute path to the specified icon \n - * If the @a path is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_icon() - */ -int ui_notification_set_icon(ui_notification_h notification, const char *path); - -/** - * @brief Gets the absolute path to the icon to display in the notification. - * @remarks The @a path must be released with free() by you. - * @param[in] notification The notification handle - * @param[out] path The absolute path to the icon - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_icon() - */ -int ui_notification_get_icon(ui_notification_h notification, char **path); - -/** - * @brief Sets the time that the notification occurred. - * @remarks This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] time The time that the notification occurred \n - * If the @a time is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_time() - */ -int ui_notification_set_time(ui_notification_h notification, struct tm *time); - -/** - * @brief Gets the time that the notification occured. - * @param[in] notification The notification handle - * @param[out] time The time that the notification occured - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_time() - */ -int ui_notification_get_time(ui_notification_h notification, struct tm **time); - -/** - * @brief Sets the title to display in the notification. - * @remarks If the title is not set, the name of the application will be displayed. \n - * This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] title The title to display in the notification \n - * If the @a title is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_title() - */ -int ui_notification_set_title(ui_notification_h notification, const char *title); - -/** - * @brief Gets the title to display in the notification. - * @remarks The @a title must be released with free() by you. - * @param[in] notification The notification handle - * @param[out] title The title to display in the notification - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_title() - */ -int ui_notification_get_title(ui_notification_h notification, char **title); - -/** - * @brief Sets the content to display in the notification - * @remarks This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] content The content to display in the notification \n - * If the @a content is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_content() - */ -int ui_notification_set_content(ui_notification_h notification, const char *content); - -/** - * @brief Gets the content to display in the notification - * @remarks The @a content must be released with free() by you. - * @param[in] notification The notification handle - * @param[out] content The content to display in the notification - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_content() - */ -int ui_notification_get_content(ui_notification_h notification, char **content); - -/** - * @brief Sets the path of sound file to play when the notification is shown. - * @remarks The @a path should be the absolute path. \n - * The sound file is only supported wave file format. \n - * This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] path The path of sound file to play when the notification is shown \n - * If the @a path is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_sound() - */ -int ui_notification_set_sound(ui_notification_h notification, const char *path); - -/** - * @brief Gets the path of sound file to play when the notification is shown. - * @remarks The @a path must be released with free() by you. - * @param[in] notification The notification handle - * @param[out] path The path of sound file to play when the notification is shown \n - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_sound() - */ -int ui_notification_get_sound(ui_notification_h notification, char **path); - -/** - * @brief Sets whether to use vibration when the notification is shown. - * @remarks This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] value A boolean value that sets whether to use vibration. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_vibration() - */ -int ui_notification_set_vibration(ui_notification_h notification, bool value); - -/** - * @brief Gets whether to use vibration when the notification is shown. - * @param[in] notification The notification handle - * @param[out] value A boolean value that sets whether to use vibration. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_vibration() - */ -int ui_notification_get_vibration(ui_notification_h notification, bool *value); - -/** - * @brief Sets the service to launch when the notification is selected from the notification tray. - * @details When the notification is selected from the notification tray, the application which is described by the specified service is launched. \n - * If you want to launch the current application, use the explicit launch of the @ref CAPI_SERVICE_MODULE API - * @remarks If the service is not set, the selected notification will be cleared from both the notification tray and the status bar without any action. \n - * This function should be called before posting or updating the notification (see ui_notification_post(), ui_notification_update()). - * @param[in] notification The notification handle - * @param[in] service The service handle to launch when the notification is selected \n - * If the @a service is NULL, it clears the previous value. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_get_service() - * @see service_create() - */ -int ui_notification_set_service(ui_notification_h notification, service_h service); - -/** - * @brief Gets the service to launch when the notification is selected from the notification tray - * @remarks The @a service must be released with service_destroy() by you. - * @param[in] notification The notification handle - * @param[out] service The service handle to launch when the notification is selected - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_set_service() - */ -int ui_notification_get_service(ui_notification_h notification, service_h *service); - -/** - * @brief Posts the notification to display in the notification tray and the status bar - * @param[in] notification The notification handle - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_DB_FAILED DB failed - * @retval #UI_NOTIFICATION_ERROR_NO_SUCH_FILE DB No such icon file - * @retval #UI_NOTIFICATION_ERROR_INVALID_STATE The notification was already posted - * @post The posted notification can be canceled or updated. - * @see ui_notification_cancel() - * @see ui_notification_cancel_all() - * @see ui_notification_update() - * @see ui_notification_update_progress() - * @see ui_notification_foreach_notification_posted() - */ -int ui_notification_post(ui_notification_h notification); - -/** - * @brief Cancels the previously posted notification. - * @details The previously posted notification is removed from the notification tray and the status bar. - * @remarks The canceled @a notification is not be released automatically, must be released with ui_notification_destroy() by you. - * @param[in] notification The notification handle - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_INVALID_STATE The notification was not posted or the notification was either cleared or canceled. - * @pre The notification must be posted before canceling it. - * @see ui_notification_post() - * @see ui_notification_cancel_all() - */ -int ui_notification_cancel(ui_notification_h notification); - -/** - * @brief Cancels all previously posted notifications by the current application. - * @details All previously posted notifications are removed from the notification tray and the status bar. - * @remarks The notifications posted by other applications are not canceled from the notification tray and the status bar. - * @see ui_notification_post() - * @see ui_notification_cancel() - */ -void ui_notification_cancel_all(void); - -/** - * @brief Cancels selected type of previously posted notifications by the current application. - * @details Selected type of previously posted notifications are removed from the notification tray and the status bar. - * @remarks The notifications posted by other applications are not cancelled from the notification tray and the status bar. - * @param[in] ongoing A boolean value that indicates whether the notification type is ongoing to cancel. - * @see ui_notification_post() - * @see ui_notification_cancel() - * @see ui_notification_cancel_all() - */ -void ui_notification_cancel_all_by_type(bool ongoing); - -/** - * @brief Cancels selected type of previously posted notifications by the given application. - * @details Selected type of previously posted notifications are removed from the notification tray and the status bar. - * @remark This function is @b deprecated. Use app_manager_app_context_cb() instead. - * @param[in] package The package name of the application to calcel the posted notifications. - * @param[in] ongoing A boolean value that indicates whether the notification type is ongoing to cancel. - * @see ui_notification_post() - * @see ui_notification_cancel() - * @see ui_notification_cancel_all() - */ -void ui_notification_cancel_all_by_package(const char *package, bool ongoing); - -/** - * @brief Cancels selected type of previously posted notifications by the given application ID. - * @details Selected type of previously posted notifications are removed from the notification tray and the status bar. - * @param[in] id The ID of the application to calcel the posted notifications. - * @param[in] ongoing A boolean value that indicates whether the notification type is ongoing to cancel. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @see ui_notification_post() - * @see ui_notification_cancel() - * @see ui_notification_cancel_all() - */ -int ui_notification_cancel_all_by_app_id(const char *app_id, bool ongoing); - -/** - * @brief Updates the notification posted. - * @remarks You cannot update the notification which was cleared or canceled. - * @param[in] notification The notification handle - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_DB_FAILED DB failed - * @retval #UI_NOTIFICATION_ERROR_NO_SUCH_FILE DB No such icon file - * @retval #UI_NOTIFICATION_ERROR_INVALID_STATE The notification was not posted or the notification was either cleared or canceled. - * @pre The notification must be posted before updating it. - * @see ui_notification_post() - * @see ui_notification_update_progress() - */ -int ui_notification_update(ui_notification_h notification); - -/** - * @brief Updates the progress to the specified value - * @remarks You cannot update the notification which was cleared or canceled. - * @param[in] notification The notification handle \n - * It must be ongoing notification. \n - * If not, #UI_NOTIFICATION_ERROR_INVALID_PARAMETER will occur - * @param[in] type The progress type - * @param[in] value The value of the progress \n - * The @a value must be greater than or equal to zero. \n - * if @a type is #UI_NOTIFICATION_PROGRESS_TYPE_SIZE, it must be in bytes. \n - * If @a type is #UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE, It must be a floating-point value between 0.0 and 1.0. - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_INVALID_STATE The notification was not posted or the notification was canceled. - * @pre The notification must be posted before updating the progress to the specified value - * @see ui_notification_create() - * @see ui_notification_post() - * @see ui_notification_update() - * @see #ui_notification_progress_type_e - */ -int ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value); - -/** - * @brief Retrieves all posted notifications. - * @details This function calls ui_notification_cb() once for each notification which was posted and is being shown. \n - * If ui_notification_cb() callback function returns false, then iteration will be finished. - * - * @param [in] ongoing A boolean value that sets whether the type is an ongoing notification. - * @param [in] callback The iteration callback function - * @param [in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @post This function invokes ui_notification_cb(). - * @see ui_notification_cb() - */ -int ui_notification_foreach_notification_posted(bool ongoing, ui_notification_cb callback, void *user_data); - -/** - * @brief Creates and returns a copy of the given notification handle. - * - * @remarks A newly created notification handle should be destroyed by calling ui_notification_destroy() if it is no longer needed. - * - * @param [out] clone If successful, a newly created notification handle will be returned. - * @param [in] service The notification handle - * @return 0 on success, otherwise a negative error value. - * @retval #UI_NOTIFICATION_ERROR_NONE Successful - * @retval #UI_NOTIFICATION_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #UI_NOTIFICATION_ERROR_OUT_OF_MEMORY Out of memory - * @see ui_notification_create() - * @see ui_notification_destroy() - */ -int ui_notification_clone(ui_notification_h *clone, ui_notification_h notification); - - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __TIZEN_APPFW_UI_NOTIFICATION_H__ */ diff --git a/packaging/capi-appfw-application.spec b/packaging/capi-appfw-application.spec index 3ff3d38..743588e 100755 --- a/packaging/capi-appfw-application.spec +++ b/packaging/capi-appfw-application.spec @@ -1,10 +1,9 @@ -#sbs-git:slp/api/application capi-appfw-application 0.1.0 56d9b8e057f022f0e7fdb1853587158452e7ae1b Name: capi-appfw-application Summary: An Application library in SLP C API -Version: 0.1.0 -Release: 28 -Group: TO_BE/FILLED_IN -License: TO BE FILLED IN +Version: 0.3.1.0 +Release: 1 +Group: Application Framework/Libraries +License: Apache-2.0 Source0: %{name}-%{version}.tar.gz BuildRequires: cmake BuildRequires: pkgconfig(dlog) @@ -14,16 +13,19 @@ BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(ail) BuildRequires: pkgconfig(appsvc) -BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(alarm-service) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(capi-security-privilege-manager) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(vconf-internal-keys) - -Requires(post): /sbin/ldconfig +Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig +%define feature_appfw_process_pool 1 + %description An Application library in SLP C API @@ -38,17 +40,22 @@ An Application library in SLP C API (DEV) %prep %setup -q - %build -MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} +%if 0%{?feature_appfw_process_pool} + _APPFW_FEATURE_PROCESS_POOL=ON +%endif +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \ + -D_APPFW_FEATURE_PROCESS_POOL:BOOL=${_APPFW_FEATURE_PROCESS_POOL} make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} %post -p /sbin/ldconfig @@ -57,11 +64,19 @@ rm -rf %{buildroot} %files %{_libdir}/libcapi-appfw-application.so.* +%{_libdir}/libcapi-appfw-app-control.so.* +%{_libdir}/libcapi-appfw-app-common.so.* +%{_libdir}/libcapi-appfw-alarm.so.* +%{_libdir}/libcapi-appfw-preference.so.* +%manifest capi-appfw-application.manifest +/usr/share/license/%{name} %files devel %{_includedir}/appfw/*.h %{_libdir}/pkgconfig/*.pc %{_libdir}/libcapi-appfw-application.so - - +%{_libdir}/libcapi-appfw-app-control.so +%{_libdir}/libcapi-appfw-app-common.so +%{_libdir}/libcapi-appfw-alarm.so +%{_libdir}/libcapi-appfw-preference.so diff --git a/preference/CMakeLists.txt b/preference/CMakeLists.txt new file mode 100644 index 0000000..aa5bc0d --- /dev/null +++ b/preference/CMakeLists.txt @@ -0,0 +1,66 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_name "capi-appfw-preference") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +SET(INC_DIR ${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +SET(requires "dlog capi-base-common sqlite3") +SET(pc_requires "capi-base-common capi-appfw-app-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${requires}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DTARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +add_library(${fw_name} SHARED + preference.c + preference_inoti.c + ) + +TARGET_LINK_LIBRARIES(${fw_name} capi-appfw-app-common ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_name} DESTINATION lib) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include/appfw + FILES_MATCHING + PATTERN "*_private.h" EXCLUDE + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_requires}) +SET(PC_LDFLAGS -l${fw_name}) + +CONFIGURE_FILE( + ${CMAKE_SOURCE_DIR}/capi-appfw-module.pc.in + ${CMAKE_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) + + diff --git a/preference/preference.c b/preference/preference.c new file mode 100755 index 0000000..f11b451 --- /dev/null +++ b/preference/preference.c @@ -0,0 +1,1533 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef PREFERENCE_TIMECHECK +#include +#endif + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#define PREFERENCE_ERROR_RETRY_CNT 7 +#define PREFERENCE_ERROR_RETRY_SLEEP_UTIME 10000 + +#define DELIMITER 29 + +static int g_posix_errno; +static int g_preference_errno; +static char *g_pref_dir_path = NULL; + +enum preference_op_t { + PREFERENCE_OP_GET = 0, + PREFERENCE_OP_SET = 1 +}; + +#ifdef PREFERENCE_TIMECHECK +double correction, startT; + +double set_start_time(void) +{ + struct timeval tv; + double curtime; + + gettimeofday(&tv, NULL); + curtime = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000; + return curtime; +} + +double exec_time(double start) +{ + double end = set_start_time(); + return (end - start - correction); +} + +int init_time(void) +{ + double temp_t; + temp_t = set_start_time(); + correction = exec_time(temp_t); + + return 0; +} +#endif + +char* _preference_get_pref_dir_path() +{ + char *app_data_path = NULL; + + if (!g_pref_dir_path) { + g_pref_dir_path = (char *)malloc(PREFERENCE_KEY_PATH_LEN + 1); + + if ((app_data_path = app_get_data_path()) == NULL) { + ERR("IO_ERROR(0x%08x) : fail to get data directory", PREFERENCE_ERROR_IO_ERROR); + free(g_pref_dir_path); + g_pref_dir_path = NULL; + return NULL; + } + + snprintf(g_pref_dir_path, PREFERENCE_KEY_PATH_LEN, "%s%s", app_data_path, PREF_DIR); + INFO("pref_dir_path: %s", g_pref_dir_path); + free(app_data_path); + } + return g_pref_dir_path; +} + +int _preference_keynode_set_keyname(keynode_t *keynode, const char *keyname) +{ + if (keynode->keyname) free(keynode->keyname); + keynode->keyname = strndup(keyname, PREFERENCE_KEY_PATH_LEN); + retvm_if(keynode->keyname == NULL, PREFERENCE_ERROR_IO_ERROR, "strndup Fails"); + return PREFERENCE_ERROR_NONE; +} + +static inline void _preference_keynode_set_value_int(keynode_t *keynode, const int value) +{ + keynode->type = PREFERENCE_TYPE_INT; + keynode->value.i = value; +} + +static inline void _preference_keynode_set_value_boolean(keynode_t *keynode, const int value) +{ + keynode->type = PREFERENCE_TYPE_BOOLEAN; + keynode->value.b = !!value; +} + +static inline void _preference_keynode_set_value_double(keynode_t *keynode, const double value) +{ + keynode->type = PREFERENCE_TYPE_DOUBLE; + keynode->value.d = value; +} + +static inline void _preference_keynode_set_value_string(keynode_t *keynode, const char *value) +{ + keynode->type = PREFERENCE_TYPE_STRING; + keynode->value.s = strdup(value); +} + +inline keynode_t *_preference_keynode_new(void) +{ + keynode_t *keynode; + keynode = calloc(1, sizeof(keynode_t)); + + return keynode; +} + +inline void _preference_keynode_free(keynode_t *keynode) +{ + if(keynode) { + if (keynode->keyname) + free(keynode->keyname); + if (keynode->type == PREFERENCE_TYPE_STRING && keynode->value.s) + free(keynode->value.s); + free(keynode); + } +} + +int _preference_get_key_name(const char *path, char **keyname) +{ + int read_size = 0; + size_t keyname_len = 0; + char *convert_key = NULL; + FILE *fp = NULL; + + if( (fp = fopen(path, "r")) == NULL ) { + return PREFERENCE_ERROR_FILE_OPEN; + } + + read_size = fread((void *)&keyname_len, sizeof(int), 1, fp); + if (read_size <= 0) { + fclose(fp); + return PREFERENCE_ERROR_FILE_FREAD; + } + + convert_key = (char *)calloc(1, keyname_len+1); + if (convert_key == NULL) { + LOGE("memory alloc failed"); + fclose(fp); + return PREFERENCE_ERROR_OUT_OF_MEMORY; + } + + read_size = fread((void *)convert_key, keyname_len, 1, fp); + if (read_size <= 0) { + free(convert_key); + fclose(fp); + return PREFERENCE_ERROR_FILE_FREAD; + } + + *keyname = convert_key; + + fclose(fp); + + return PREFERENCE_ERROR_NONE; +} + +int _preference_get_key_path(keynode_t *keynode, char *path) +{ + const char *key = NULL; + char *pref_dir_path = NULL; + gchar *convert_key; + char *keyname = keynode->keyname; + + if(!keyname) { + LOGE("keyname is null"); + return PREFERENCE_ERROR_WRONG_PREFIX; + } + + pref_dir_path = _preference_get_pref_dir_path(); + if (!pref_dir_path) { + LOGE("_preference_get_pref_dir_path() failed."); + return PREFERENCE_ERROR_IO_ERROR; + } + + convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1, + keyname, + strlen(keyname)); + if (convert_key == NULL) { + LOGE("fail to convert"); + return PREFERENCE_ERROR_IO_ERROR; + } + + key = (const char*)convert_key; + + snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, key); + + g_free(convert_key); + + return PREFERENCE_ERROR_NONE; +} + +static int _preference_set_key_check_pref_dir() +{ + char *pref_dir_path = NULL; + mode_t dir_mode = 0664 | 0111; + + pref_dir_path = _preference_get_pref_dir_path(); + if (!pref_dir_path) { + LOGE("_preference_get_pref_dir_path() failed."); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (access(pref_dir_path, F_OK) < 0) { + if (mkdir(pref_dir_path, dir_mode) < 0) { + ERR("mkdir() failed(%d/%s)", errno, strerror(errno)); + return PREFERENCE_ERROR_IO_ERROR; + } + } + + return PREFERENCE_ERROR_NONE; +} + +static int _preference_set_key_creation(const char* path) +{ + int fd; + mode_t temp; + temp = umask(0000); + fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); + umask(temp); + + if(fd == -1) { + ERR("open(rdwr,create) error: %d(%s)", errno, strerror(errno)); + return PREFERENCE_ERROR_IO_ERROR; + } + close(fd); + + return PREFERENCE_ERROR_NONE; +} + +static int _preference_set_file_lock(int fd, short type) +{ + struct flock l; + + l.l_type = type; + l.l_start= 0; /*Start at begin*/ + l.l_whence = SEEK_SET; + l.l_len = 0; /*Do it with whole file*/ + + return fcntl(fd, F_SETLK, &l); +} + +static int _preference_get_pid_of_file_lock_owner(int fd, short type) +{ + struct flock l; + + l.l_type = type; + l.l_start= 0; /*Start at begin*/ + l.l_whence = SEEK_SET; + l.l_len = 0; /*Do it with whole file*/ + + if(fcntl(fd, F_GETLK, &l) < 0) { + WARN("error in getting lock info"); + return -1; + } + + if(l.l_type == F_UNLCK) + return 0; + else + return l.l_pid; +} + + +static int _preference_set_read_lock(int fd) +{ + return _preference_set_file_lock(fd, F_RDLCK); +} + +static int _preference_set_write_lock(int fd) +{ + return _preference_set_file_lock(fd, F_WRLCK); +} + +static int _preference_set_unlock(int fd) +{ + return _preference_set_file_lock(fd, F_UNLCK); +} + +static void _preference_log_subject_label(void) +{ + int fd; + int ret; + char smack_label[256] = {0,}; + char curren_path[256] = {0,}; + int tid; + + tid = (int)syscall(SYS_gettid); + snprintf(curren_path, sizeof(curren_path)-1, "/proc/%d/attr/current", tid); + fd = open(curren_path, O_RDONLY); + if (fd < 0) { + LOGE("fail to open self current attr (err: %s)", strerror(errno)); + return; + } + + ret = read(fd, smack_label, sizeof(smack_label)-1); + if (ret < 0) { + close(fd); + LOGE("fail to open self current attr (err: %s)", strerror(errno)); + return; + } + + ERR("current(%d) subject label : %s", tid, smack_label); + + close(fd); +} + +static int _preference_check_retry_err(keynode_t *keynode, int preference_errno, int io_errno, int op_type) +{ + int is_busy_err = 0; + + if (preference_errno == PREFERENCE_ERROR_FILE_OPEN) + { + switch (io_errno) + { + case ENOENT : + { + if(op_type == PREFERENCE_OP_SET) + { + int rc = 0; + char path[PATH_MAX] = {0,}; + rc = _preference_get_key_path(keynode, path); + if (rc != PREFERENCE_ERROR_NONE) { + ERR("_preference_get_key_path error"); + _preference_log_subject_label(); + break; + } + + rc = _preference_set_key_check_pref_dir(); + if (rc != PREFERENCE_ERROR_NONE) { + ERR("_preference_set_key_check_pref_dir() failed."); + _preference_log_subject_label(); + break; + } + + rc = _preference_set_key_creation(path); + if (rc != PREFERENCE_ERROR_NONE) { + ERR("_preference_set_key_creation error : %s", path); + _preference_log_subject_label(); + break; + } + INFO("%s key is created", keynode->keyname); + + is_busy_err = 1; + } + break; + } + case EACCES : + { + _preference_log_subject_label(); + break; + } + case EAGAIN : + case EMFILE : + case ENFILE : + case ETXTBSY : + { + is_busy_err = 1; + } + } + } + else if (preference_errno == PREFERENCE_ERROR_FILE_CHMOD) + { + switch (io_errno) + { + case EINTR : + case EBADF : + { + is_busy_err = 1; + } + } + } + else if (preference_errno == PREFERENCE_ERROR_FILE_LOCK) + { + switch (io_errno) + { + case EBADF : + case EAGAIN : + case ENOLCK : + { + is_busy_err = 1; + } + } + } + else if (preference_errno == PREFERENCE_ERROR_FILE_WRITE) + { + switch (io_errno) + { + case 0 : + case EAGAIN : + case EINTR : + case EIO : + case ENOMEM : + { + is_busy_err = 1; + } + } + } + else if (preference_errno == PREFERENCE_ERROR_FILE_FREAD) + { + switch (io_errno) + { + case EAGAIN : + case EINTR : + case EIO : + { + is_busy_err = 1; + } + } + } + else + { + is_busy_err = 0; + } + + if (is_busy_err == 1) { + return 1; + } + else + { + ERR("key(%s), check retry err: %d/(%d/%s).",keynode->keyname, preference_errno, io_errno, strerror(io_errno)); + return 0; + } +} + +static int _preference_set_key_filesys(keynode_t *keynode, int *io_errno) +{ + char path[PATH_MAX] = {0,}; + FILE *fp = NULL; + int ret = -1; + int func_ret = PREFERENCE_ERROR_NONE; + int err_no = 0; + char err_buf[100] = { 0, }; + int is_write_error = 0; + int retry_cnt = 0; + size_t keyname_len = 0; + +retry_open : + errno = 0; + err_no = 0; + func_ret = PREFERENCE_ERROR_NONE; + + ret = _preference_get_key_path(keynode, path); + retv_if(ret != PREFERENCE_ERROR_NONE, ret); + + if( (fp = fopen(path, "r+")) == NULL ) { + func_ret = PREFERENCE_ERROR_FILE_OPEN; + err_no = errno; + goto out_return; + } + +retry : + errno = 0; + err_no = 0; + func_ret = PREFERENCE_ERROR_NONE; + + ret = _preference_set_write_lock(fileno(fp)); + if (ret == -1) { + func_ret = PREFERENCE_ERROR_FILE_LOCK; + err_no = errno; + ERR("file(%s) lock owner(%d)", + keynode->keyname, + _preference_get_pid_of_file_lock_owner(fileno(fp), F_WRLCK)); + goto out_return; + } + + /* write keyname and size */ + keyname_len = strlen(keynode->keyname); + + ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp); + if (ret <= 0) { + if (!errno) { + LOGW("number of written items is 0. try again"); + errno = EAGAIN; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_WRITE; + goto out_unlock; + } + + ret = fwrite((void *)keynode->keyname, keyname_len, 1, fp); + if (ret <= 0) { + if (!errno) { + LOGW("number of written items is 0. try again"); + errno = EAGAIN; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_WRITE; + goto out_unlock; + } + + /* write key type */ + ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp); + if (ret <= 0) { + if (!errno) { + LOGW("number of written items is 0. try again"); + errno = EAGAIN; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_WRITE; + goto out_unlock; + } + + /* write key value */ + switch (keynode->type) { + case PREFERENCE_TYPE_INT: + ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp); + if (ret <= 0) is_write_error = 1; + break; + case PREFERENCE_TYPE_DOUBLE: + ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp); + if (ret <= 0) is_write_error = 1; + break; + case PREFERENCE_TYPE_BOOLEAN: + ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp); + if (ret <= 0) is_write_error = 1; + break; + case PREFERENCE_TYPE_STRING: + ret = fprintf(fp,"%s",keynode->value.s); + if (ret < strlen(keynode->value.s)) is_write_error = 1; + if (ftruncate(fileno(fp), ret) == -1) + is_write_error = 1; + break; + default : + func_ret = PREFERENCE_ERROR_WRONG_TYPE; + goto out_unlock; + } + + if (is_write_error) { + if (!errno) { + LOGW("number of written items is 0. try again"); + errno = EAGAIN; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_WRITE; + goto out_unlock; + } + + fflush(fp); + +out_unlock : + ret = _preference_set_unlock(fileno(fp)); + if (ret == -1) { + func_ret = PREFERENCE_ERROR_FILE_LOCK; + err_no = errno; + goto out_return; + } + +out_return : + if (func_ret != PREFERENCE_ERROR_NONE) { + strerror_r(err_no, err_buf, 100); + if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_SET)) { + if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT) { + WARN("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s) retry(%d)", keynode->type, keynode->keyname, func_ret, err_no, err_buf, retry_cnt); + retry_cnt++; + usleep((retry_cnt)*PREFERENCE_ERROR_RETRY_SLEEP_UTIME); + + if (fp) + goto retry; + else + goto retry_open; + } else { + ERR("_preference_set_key_filesys(%d-%s) step(%d) faild(%d / %s) over the retry count.", + keynode->type, keynode->keyname, func_ret, err_no, err_buf); + } + } else { + ERR("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf); + } + } else { + if(retry_cnt > 0) { + DBG("_preference_set_key_filesys ok with retry cnt(%d)", retry_cnt); + } + } + + if (fp) { + if (func_ret == PREFERENCE_ERROR_NONE) { + ret = fdatasync(fileno(fp)); + if (ret == -1) { + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_SYNC; + } + } + fclose(fp); + } + *io_errno = err_no; + + return func_ret; +} + +static int _preference_set_key(keynode_t *keynode) +{ + int ret = 0; + int io_errno = 0; + char err_buf[100] = { 0, }; + + ret = _preference_set_key_filesys(keynode, &io_errno); + if (ret == PREFERENCE_ERROR_NONE) { + g_posix_errno = PREFERENCE_ERROR_NONE; + g_preference_errno = PREFERENCE_ERROR_NONE; + } else { + strerror_r(io_errno, err_buf, 100); + ERR("_preference_set_key(%s) step(%d) failed(%d / %s)", keynode->keyname, ret, io_errno, err_buf); + g_posix_errno = io_errno; + g_preference_errno = ret; + } + + return ret; +} + + +/* + * This function set the integer value of given key + * @param[in] key key + * @param[in] intval integer value to set + * @return 0 on success, -1 on error + */ +API int preference_set_int(const char *key, int intval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL"); + + int func_ret = PREFERENCE_ERROR_NONE; + + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + _preference_keynode_set_value_int(pKeyNode, intval); + + if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) { + ERR("preference_set_int(%d) : key(%s/%d) error", getpid(), key, intval); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + INFO("%s(%d) success", key, intval); + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* +* This function set the boolean value of given key +* @param[in] key key +* @param[in] boolval boolean value to set + (Integer value 1 is 'True', and 0 is 'False') +* @return 0 on success, -1 on error +*/ +API int preference_set_boolean(const char *key, bool boolval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL"); + + int func_ret = PREFERENCE_ERROR_NONE; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + _preference_keynode_set_value_boolean(pKeyNode, boolval); + + if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) { + ERR("preference_set_boolean(%d) : key(%s/%d) error", getpid(), key, boolval); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + INFO("%s(%d) success", key, boolval); + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function set the double value of given key + * @param[in] key key + * @param[in] dblval double value to set + * @return 0 on success, -1 on error + */ +API int preference_set_double(const char *key, double dblval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL"); + + int func_ret = PREFERENCE_ERROR_NONE; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + _preference_keynode_set_value_double(pKeyNode, dblval); + + if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) { + ERR("preference_set_double(%d) : key(%s/%f) error", getpid(), key, dblval); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + INFO("%s(%f) success", key, dblval); + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function set the string value of given key + * @param[in] key key + * @param[in] strval string value to set + * @return 0 on success, -1 on error + */ +API int preference_set_string(const char *key, const char *strval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL"); + retvm_if(strval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: value is NULL"); + + int func_ret = PREFERENCE_ERROR_NONE; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + _preference_keynode_set_value_string(pKeyNode, strval); + + if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) { + ERR("preference_set_string(%d) : key(%s/%s) error", getpid(), key, strval); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + INFO("%s(%s) success", key, strval); + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +static int _preference_get_key_filesys(keynode_t *keynode, int* io_errno) +{ + char path[PATH_MAX] = {0,}; + int ret = -1; + int func_ret = PREFERENCE_ERROR_NONE; + char err_buf[100] = { 0, }; + int err_no = 0; + int type = 0; + FILE *fp = NULL; + int retry_cnt = 0; + int read_size = 0; + size_t keyname_len = 0; + +retry_open : + errno = 0; + func_ret = PREFERENCE_ERROR_NONE; + + ret = _preference_get_key_path(keynode, path); + retv_if(ret != PREFERENCE_ERROR_NONE, ret); + + if( (fp = fopen(path, "r")) == NULL ) { + func_ret = PREFERENCE_ERROR_FILE_OPEN; + err_no = errno; + goto out_return; + } + +retry : + err_no = 0; + func_ret = PREFERENCE_ERROR_NONE; + + ret = _preference_set_read_lock(fileno(fp)); + if (ret == -1) { + func_ret = PREFERENCE_ERROR_FILE_LOCK; + err_no = errno; + goto out_return; + } + + read_size = fread((void *)&keyname_len, sizeof(int), 1, fp); + if ((read_size <= 0) || (read_size > sizeof(int))) { + if(!ferror(fp)) { + errno = ENODATA; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } + + ret = fseek(fp, keyname_len, SEEK_CUR); + if (ret) { + if(!ferror(fp)) { + errno = ENODATA; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } + + read_size = fread((void *)&type, sizeof(int), 1, fp); + if (read_size <= 0) { + if(!ferror(fp)) { + errno = ENODATA; + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } + + /* read data value */ + switch(type) + { + case PREFERENCE_TYPE_INT: + { + int value_int = 0; + read_size = fread((void*)&value_int, sizeof(int), 1, fp); + if ((read_size <= 0) || (read_size > sizeof(int))) { + if (!ferror(fp)) { + LOGW("number of read items for value is wrong. err : %d", errno); + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } else { + _preference_keynode_set_value_int(keynode, value_int); + } + + break; + } + case PREFERENCE_TYPE_DOUBLE: + { + double value_dbl = 0; + read_size = fread((void*)&value_dbl, sizeof(double), 1, fp); + if ((read_size <= 0) || (read_size > sizeof(double))) { + if (!ferror(fp)) { + LOGW("number of read items for value is wrong. err : %d", errno); + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } else { + _preference_keynode_set_value_double(keynode, value_dbl); + } + + break; + } + case PREFERENCE_TYPE_BOOLEAN: + { + int value_int = 0; + read_size = fread((void*)&value_int, sizeof(int), 1, fp); + if ((read_size <= 0) || (read_size > sizeof(int))) { + if (!ferror(fp)) { + LOGW("number of read items for value is wrong. err : %d", errno); + } + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FREAD; + goto out_unlock; + } else { + _preference_keynode_set_value_boolean(keynode, value_int); + } + + break; + } + case PREFERENCE_TYPE_STRING: + { + char file_buf[BUF_LEN] = {0,}; + char *value = NULL; + int value_size = 0; + + while(fgets(file_buf, sizeof(file_buf), fp)) + { + if (value) { + value_size = value_size + strlen(file_buf); + value = (char *) realloc(value, value_size); + if (value == NULL) { + func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY; + break; + } + strncat(value, file_buf, strlen(file_buf)); + } else { + value_size = strlen(file_buf) + 1; + value = (char *)malloc(value_size); + if (value == NULL) { + func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY; + break; + } + memset(value, 0x00, value_size); + strncpy(value, file_buf, strlen(file_buf)); + } + } + + if (ferror(fp)) { + err_no = errno; + func_ret = PREFERENCE_ERROR_FILE_FGETS; + } else { + if (value) { + _preference_keynode_set_value_string(keynode, value); + } else { + _preference_keynode_set_value_string(keynode, ""); + } + } + if (value) + free(value); + + break; + } + default : + func_ret = PREFERENCE_ERROR_WRONG_TYPE; + } + +out_unlock : + ret = _preference_set_unlock(fileno(fp)); + if (ret == -1) { + func_ret = PREFERENCE_ERROR_FILE_LOCK; + err_no = errno; + goto out_return; + } + + +out_return : + if (func_ret != PREFERENCE_ERROR_NONE) { + strerror_r(err_no, err_buf, 100); + + if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_GET)) { + if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT) { + retry_cnt++; + usleep((retry_cnt)*PREFERENCE_ERROR_RETRY_SLEEP_UTIME); + + if (fp) + goto retry; + else + goto retry_open; + } + else { + ERR("_preference_get_key_filesys(%s) step(%d) faild(%d / %s) over the retry count.", + keynode->keyname, func_ret, err_no, err_buf); + } + } + } + + if (fp) + fclose(fp); + + *io_errno = err_no; + + return func_ret; +} + +int _preference_get_key(keynode_t *keynode) +{ + int ret = 0; + int io_errno = 0; + char err_buf[100] = {0,}; + + ret = _preference_get_key_filesys(keynode, &io_errno); + if (ret == PREFERENCE_ERROR_NONE) { + g_posix_errno = PREFERENCE_ERROR_NONE; + g_preference_errno = PREFERENCE_ERROR_NONE; + } + else { + if (io_errno == ENOENT) + ret = PREFERENCE_ERROR_NO_KEY; + else + ret = PREFERENCE_ERROR_IO_ERROR; + + strerror_r(io_errno, err_buf, 100); + ERR("_preference_get_key(%s) step(%d) failed(%d / %s)\n", keynode->keyname, ret, io_errno, err_buf); + g_posix_errno = io_errno; + g_preference_errno = ret; + } + + return ret; +} + + +/* + * This function get the integer value of given key + * @param[in] key key + * @param[out] intval output buffer + * @return 0 on success, -1 on error + */ +API int preference_get_int(const char *key, int *intval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(intval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null"); + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + func_ret = _preference_get_key(pKeyNode); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("preference_get_int(%d) : key(%s) error", getpid(), key); + } else { + *intval = pKeyNode->value.i; + if (pKeyNode->type == PREFERENCE_TYPE_INT) { + INFO("%s(%d) success", key, *intval); + func_ret = PREFERENCE_ERROR_NONE; + } else { + ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname); + func_ret = PREFERENCE_ERROR_INVALID_PARAMETER; + } + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function get the boolean value of given key + * @param[in] key key + * @param[out] boolval output buffer + * @return 0 on success, -1 on error + */ +API int preference_get_boolean(const char *key, bool *boolval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(boolval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null"); + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + func_ret = _preference_get_key(pKeyNode); + + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("preference_get_boolean(%d) : %s error", getpid(), key); + } else { + *boolval = !!(pKeyNode->value.b); + if (pKeyNode->type == PREFERENCE_TYPE_BOOLEAN) { + INFO("%s(%d) success", key, *boolval); + func_ret = PREFERENCE_ERROR_NONE; + } else { + ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname); + func_ret = PREFERENCE_ERROR_INVALID_PARAMETER; + } + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function get the double value of given key + * @param[in] key key + * @param[out] dblval output buffer + * @return 0 on success, -1 on error + */ +API int preference_get_double(const char *key, double *dblval) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(dblval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null"); + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + func_ret = _preference_get_key(pKeyNode); + + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("preference_get_double(%d) : %s error", getpid(), key); + } else { + *dblval = pKeyNode->value.d; + if (pKeyNode->type == PREFERENCE_TYPE_DOUBLE) { + INFO("%s(%f) success", key, *dblval); + func_ret = PREFERENCE_ERROR_NONE; + } else { + ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname); + func_ret = PREFERENCE_ERROR_INVALID_PARAMETER; + } + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function get the string value of given key + * @param[in] key key + * @param[out] value output buffer + * @return 0 on success, -1 on error + */ +API int preference_get_string(const char *key, char **value) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(value == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null"); + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + char *tempstr = NULL; + func_ret = _preference_get_key(pKeyNode); + + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("preference_get_string(%d) : %s error", getpid(), key); + } else { + if (pKeyNode->type == PREFERENCE_TYPE_STRING) + tempstr = pKeyNode->value.s; + else { + ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname); + func_ret = PREFERENCE_ERROR_INVALID_PARAMETER; + } + + if(tempstr) { + *value = strdup(tempstr); + INFO("%s(%s) success", key, value); + } + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + +/* + * This function unset given key + * @param[in] key key + * @return 0 on success, -1 on error + */ +API int preference_remove(const char *key) +{ + START_TIME_CHECK + + char path[PATH_MAX] = {0,}; + int ret = -1; + int err_retry = PREFERENCE_ERROR_RETRY_CNT; + int func_ret = PREFERENCE_ERROR_NONE; + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + ret = _preference_keynode_set_keyname(pKeyNode, key); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = _preference_get_key_path(pKeyNode, path); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("Invalid argument: key is not valid"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + + if (access(path, F_OK) == -1) { + ERR("Error : key(%s) is not exist", key); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_NO_KEY; + } + + do { + ret = remove(path); + if(ret == -1) { + ERR("preference_remove() failed. ret=%d(%s), key(%s)", errno, strerror(errno), key); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + func_ret = PREFERENCE_ERROR_NONE; + break; + } + } while(err_retry--); + + END_TIME_CHECK; + + _preference_keynode_free(pKeyNode); + + return func_ret; +} + +API int preference_remove_all(void) +{ + START_TIME_CHECK + + int ret = -1; + int err_retry = PREFERENCE_ERROR_RETRY_CNT; + int func_ret = PREFERENCE_ERROR_NONE; + DIR *dir; + struct dirent *dent = NULL; + char *pref_dir_path = NULL; + + pref_dir_path = _preference_get_pref_dir_path(); + if (!pref_dir_path) + { + LOGE("_preference_get_pref_dir_path() failed."); + return PREFERENCE_ERROR_IO_ERROR; + } + + dir = opendir(pref_dir_path); + if (dir == NULL) + { + LOGE("opendir() failed. pref_path: %s, error: %d(%s)", pref_dir_path, errno, strerror(errno)); + return PREFERENCE_ERROR_IO_ERROR; + } + + keynode_t* pKeyNode = _preference_keynode_new(); + if (pKeyNode == NULL) + { + ERR("key malloc fail"); + closedir(dir); + return PREFERENCE_ERROR_OUT_OF_MEMORY; + } + + while ((dent = readdir(dir))) + { + const char *entry = dent->d_name; + char *keyname = NULL; + char path[PATH_MAX] = {0,}; + + if (entry[0] == '.') { + continue; + } + + snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry); + + ret = _preference_get_key_name(path, &keyname); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("_preference_get_key_name() failed(%d)", ret); + _preference_keynode_free(pKeyNode); + closedir(dir); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = preference_unset_changed_cb(keyname); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("preference_unset_changed_cb() failed(%d)", ret); + _preference_keynode_free(pKeyNode); + closedir(dir); + free(keyname); + return PREFERENCE_ERROR_IO_ERROR; + } + + do { + ret = remove(path); + if (ret == -1) { + ERR("preference_remove_all error: %d(%s)", errno, strerror(errno)); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } else { + func_ret = PREFERENCE_ERROR_NONE; + break; + } + } while(err_retry--); + + free(keyname); + } + + _preference_keynode_free(pKeyNode); + closedir(dir); + + END_TIME_CHECK + + return func_ret; +} + +int preference_is_existing(const char *key, bool *exist) +{ + START_TIME_CHECK + + char path[PATH_MAX] = {0,}; + int ret = -1; + int func_ret = PREFERENCE_ERROR_NONE; + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(exist == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + ret = _preference_keynode_set_keyname(pKeyNode, key); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = _preference_get_key_path(pKeyNode, path); + if (ret != PREFERENCE_ERROR_NONE) { + _preference_keynode_free(pKeyNode); + return ret; + } + + ret = access(path, F_OK); + if (ret == -1) { + ERR("Error : key(%s) is not exist", key); + *exist = 0; + } else { + *exist = 1; + } + + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return func_ret; +} + + +API int preference_set_changed_cb(const char *key, preference_changed_cb callback, void *user_data) +{ + START_TIME_CHECK + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + retvm_if(callback == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: cb(%p)", callback); + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (_preference_kdb_add_notify(pKeyNode, callback, user_data)) { + if (errno == ENOENT) { + LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_NO_KEY; + } else if(errno != 0) { + ERR("preference_notify_key_changed : key(%s) add notify fail", key); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + } + INFO("%s noti is added", key); + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return PREFERENCE_ERROR_NONE; +} + +API int preference_unset_changed_cb(const char *key) +{ + START_TIME_CHECK + + int func_ret = PREFERENCE_ERROR_IO_ERROR; + + retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null"); + + keynode_t* pKeyNode = _preference_keynode_new(); + retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail"); + + func_ret = _preference_keynode_set_keyname(pKeyNode, key); + if (func_ret != PREFERENCE_ERROR_NONE) { + ERR("set key name error"); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (_preference_kdb_del_notify(pKeyNode)) { + if (errno == ENOENT) { + LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_NO_KEY; + } else if (errno != 0) { + ERR("preference_unset_changed_cb() failed: key(%s) error(%d/%s)", key, errno, strerror(errno)); + _preference_keynode_free(pKeyNode); + return PREFERENCE_ERROR_IO_ERROR; + } + } + INFO("%s noti removed", key); + _preference_keynode_free(pKeyNode); + + END_TIME_CHECK + + return PREFERENCE_ERROR_NONE; +} + + +API int preference_foreach_item(preference_item_cb callback, void *user_data) +{ + START_TIME_CHECK + + retvm_if(callback == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: cb(%p)", callback); + + int ret = 0; + DIR *dir; + struct dirent *dent = NULL; + char *pref_dir_path = NULL; + + pref_dir_path = _preference_get_pref_dir_path(); + if (!pref_dir_path) { + LOGE("_preference_get_pref_dir_path() failed."); + return PREFERENCE_ERROR_IO_ERROR; + } + + dir = opendir(pref_dir_path); + if (dir == NULL) { + LOGE("opendir() failed. path: %s, error: %d(%s)", pref_dir_path, errno, strerror(errno)); + return PREFERENCE_ERROR_IO_ERROR; + } + + while((dent = readdir(dir))) { + const char *entry = dent->d_name; + char *keyname = NULL; + char path[PATH_MAX] = {0,}; + + if (entry[0] == '.') { + continue; + } + + snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry); + + ret = _preference_get_key_name(path, &keyname); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("_preference_get_key_name() failed(%d)", ret); + closedir(dir); + return PREFERENCE_ERROR_IO_ERROR; + } + + callback(keyname, user_data); + free(keyname); + } + + closedir(dir); + END_TIME_CHECK + + return PREFERENCE_ERROR_NONE; +} diff --git a/src/preference.c b/preference/preference_db.c similarity index 58% rename from src/preference.c rename to preference/preference_db.c index ee1606b..31e9e9f 100755 --- a/src/preference.c +++ b/preference/preference_db.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -14,17 +14,16 @@ * limitations under the License. */ - #include #include #include #include #include -#include +#include #include -#include +#include #include @@ -32,7 +31,7 @@ #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_PREFERENCE" +#define LOG_TAG "CAPI_APPFW_APPLICATION_PREFERENCE" #define DBG_MODE (1) static sqlite3 *pref_db = NULL; @@ -48,33 +47,51 @@ static void _finish(void *data) } } +static int _busy_handler(void *pData, int count) +{ + if(5 - count > 0) { + LOGD("Busy Handler Called! : PID(%d) / CNT(%d)\n", getpid(), count+1); + usleep((count+1)*100000); + return 1; + } else { + LOGD("Busy Handler will be returned SQLITE_BUSY error : PID(%d) \n", getpid()); + return 0; + } +} + static int _initialize(void) { - char data_path[TIZEN_PATH_MAX] = {0, }; + char *data_path = NULL; char db_path[TIZEN_PATH_MAX] = {0, }; int ret; char *errmsg; - if (app_get_data_directory(data_path, sizeof(data_path)) == NULL) + if ((data_path = app_get_data_path()) == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to get data directory", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to get data directory", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } snprintf(db_path, sizeof(db_path), "%s/%s", data_path, PREF_DB_NAME); + free(data_path); ret = sqlite3_open(db_path, &pref_db); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to open db(%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db)); + LOGE("IO_ERROR(0x%08x) : fail to open db(%s)", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db)); pref_db = NULL; return PREFERENCE_ERROR_IO_ERROR; } + ret = sqlite3_busy_handler(pref_db, _busy_handler, NULL); + if (ret != SQLITE_OK) { + LOGW("IO_ERROR(0x%08x) : fail to register busy handler(%s)\n", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db)); + } + ret = sqlite3_exec(pref_db, "CREATE TABLE IF NOT EXISTS pref ( pref_key TEXT PRIMARY KEY, pref_type TEXT, pref_data TEXT)", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create db table(%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); + LOGE("IO_ERROR(0x%08x) : fail to create db table(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg); sqlite3_free(errmsg); sqlite3_close(pref_db); pref_db = NULL; @@ -86,17 +103,16 @@ static int _initialize(void) return PREFERENCE_ERROR_NONE; } -//static int _write_data(const char *key, preference_type_e type, const char *data) static int _write_data(const char *key, const char *type, const char *data) { int ret; - char *buf; - char *errmsg; + char *buf = NULL; bool exist = false; + sqlite3_stmt *stmt; if (key == NULL || key[0] == '\0' || data == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -110,30 +126,107 @@ static int _write_data(const char *key, const char *type, const char *data) // to use sqlite3_update_hook, we have to use INSERT/UPDATE operation instead of REPLACE operation if (exist) { - buf = sqlite3_mprintf("UPDATE %s SET %s='%s', %s='%s' WHERE %s='%s';", - PREF_TBL_NAME, PREF_F_TYPE_NAME, type, PREF_F_DATA_NAME, data, PREF_F_KEY_NAME, key); + buf = sqlite3_mprintf("UPDATE %s SET %s=?, %s=? WHERE %s=?;", + PREF_TBL_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_F_KEY_NAME); } else { - buf = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s) values ('%q', '%q', '%q');", - PREF_TBL_NAME, PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, key, type, data); + buf = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s) values (?, ?, ?);", + PREF_TBL_NAME, PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME); } if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } - ret = sqlite3_exec(pref_db, buf, NULL, NULL, &errmsg); - sqlite3_free(buf); - if (ret != SQLITE_OK) + ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + return PREFERENCE_ERROR_IO_ERROR; + } + + if(exist) { - LOGE("[%s] IO_ERROR(0x%08x): fail to write data(%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); - sqlite3_free(errmsg); + ret = sqlite3_bind_text(stmt, 1, type, strlen(type), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + ret = sqlite3_bind_text(stmt, 2, data, strlen(data), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + ret = sqlite3_bind_text(stmt, 3, key, strlen(key), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + } + else + { + ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + ret = sqlite3_bind_text(stmt, 2, type, strlen(type), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + ret = sqlite3_bind_text(stmt, 3, data, strlen(data), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("IO_ERROR(0x%08x): fail to write data(%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); return PREFERENCE_ERROR_IO_ERROR; } + sqlite3_finalize(stmt); + if(buf) { + sqlite3_free(buf); + buf = NULL; + } + return PREFERENCE_ERROR_NONE; } @@ -149,7 +242,7 @@ static int _read_data(const char *key, char *type, char *data) if (key == NULL || key[0] == '\0' || data == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -157,17 +250,17 @@ static int _read_data(const char *key, char *type, char *data) { if (_initialize() != PREFERENCE_ERROR_NONE) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to initialize db", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } } - buf = sqlite3_mprintf("SELECT %s, %s, %s FROM %s WHERE %s='%q';", + buf = sqlite3_mprintf("SELECT %s, %s, %s FROM %s WHERE %s=%Q;", PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key); if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } @@ -175,14 +268,14 @@ static int _read_data(const char *key, char *type, char *data) sqlite3_free(buf); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to read data (%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); + LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg); sqlite3_free(errmsg); return PREFERENCE_ERROR_IO_ERROR; } if (rows == 0) { - LOGE("[%s] NO_KEY(0x%08x) : fail to find given key(%s)", __FUNCTION__, PREFERENCE_ERROR_NO_KEY, key); + LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key); sqlite3_free_table(result); return PREFERENCE_ERROR_NO_KEY; } @@ -211,6 +304,11 @@ int preference_get_int(const char *key, int *value) char data[BUF_LEN]; int ret; + if (value == NULL) { + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + ret = _read_data(key, type, data); if (ret == PREFERENCE_ERROR_NONE) { @@ -220,7 +318,7 @@ int preference_get_int(const char *key, int *value) } else { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : param type(%d)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); + LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); return PREFERENCE_ERROR_INVALID_PARAMETER; } } @@ -232,8 +330,16 @@ int preference_set_double(const char *key, double value) { char type[2]; char data[BUF_LEN]; + + locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL); + uselocale(loc); + snprintf(type, 2, "%d", PREFERENCE_TYPE_DOUBLE); snprintf(data, BUF_LEN, "%f", value); + + freelocale(loc); + uselocale(LC_GLOBAL_LOCALE); + return _write_data(key, type, data); } @@ -244,16 +350,27 @@ int preference_get_double(const char *key, double *value) int ret; + if (value == NULL) { + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + ret = _read_data(key, type, data); if (ret == PREFERENCE_ERROR_NONE) { if (atoi(type) == PREFERENCE_TYPE_DOUBLE) { + locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL); + uselocale(loc); + *value = atof(data); + + freelocale(loc); + uselocale(LC_GLOBAL_LOCALE); } else { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : param type(%d)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); + LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); return PREFERENCE_ERROR_INVALID_PARAMETER; } } @@ -265,12 +382,12 @@ int preference_set_string(const char *key, const char *value) { char type[2]; + snprintf(type, 2, "%d", PREFERENCE_TYPE_STRING); if (strlen(value) > (BUF_LEN-1)) { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : param type(%d)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); + LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); return PREFERENCE_ERROR_INVALID_PARAMETER; } - snprintf(type, 2, "%d", PREFERENCE_TYPE_STRING); return _write_data(key, type, value); } @@ -283,7 +400,7 @@ int preference_get_string(const char *key, char **value) if (value == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -295,13 +412,13 @@ int preference_get_string(const char *key, char **value) *value = strdup(data); if (value == NULL) { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_OUT_OF_MEMORY); + LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY); return PREFERENCE_ERROR_OUT_OF_MEMORY; } } else { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : param type(%d)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); + LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); return PREFERENCE_ERROR_INVALID_PARAMETER; } } @@ -325,6 +442,11 @@ int preference_get_boolean(const char *key, bool *value) int ret; + if (value == NULL) { + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + ret = _read_data(key, type, data); if (ret == PREFERENCE_ERROR_NONE) { @@ -334,7 +456,7 @@ int preference_get_boolean(const char *key, bool *value) } else { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : param type(%d)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); + LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type)); return PREFERENCE_ERROR_INVALID_PARAMETER; } } @@ -355,7 +477,7 @@ int preference_is_existing(const char *key, bool *exist) if (key == NULL || key[0] == '\0' || exist == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -363,17 +485,17 @@ int preference_is_existing(const char *key, bool *exist) { if (_initialize() != PREFERENCE_ERROR_NONE) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to initialize db", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } } /* check data is exist */ - buf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s='%q';", PREF_F_KEY_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key); + buf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s=%Q;", PREF_F_KEY_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key); if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } @@ -381,7 +503,7 @@ int preference_is_existing(const char *key, bool *exist) sqlite3_free(buf); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to read data(%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); + LOGE("IO_ERROR(0x%08x) : fail to read data(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg); sqlite3_free(errmsg); return PREFERENCE_ERROR_IO_ERROR; } @@ -429,7 +551,7 @@ static int _add_node(const char *key, preference_changed_cb cb, void *user_data) if (key == NULL || key[0] == '\0' || cb == NULL) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -445,7 +567,7 @@ static int _add_node(const char *key, preference_changed_cb cb, void *user_data) tmp_node = (pref_changed_cb_node_t*)malloc(sizeof(pref_changed_cb_node_t)); if (tmp_node == NULL) { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_OUT_OF_MEMORY); + LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY); return PREFERENCE_ERROR_OUT_OF_MEMORY; } @@ -453,9 +575,12 @@ static int _add_node(const char *key, preference_changed_cb cb, void *user_data) if (tmp_node->key == NULL) { free(tmp_node); - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_OUT_OF_MEMORY); + LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY); return PREFERENCE_ERROR_OUT_OF_MEMORY; } + + if (head != NULL) + head->prev = tmp_node; tmp_node->cb = cb; tmp_node->user_data = user_data; tmp_node->prev = NULL; @@ -472,7 +597,7 @@ static int _remove_node(const char *key) if (key == NULL || key[0] == '\0' ) { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); return PREFERENCE_ERROR_INVALID_PARAMETER; } @@ -545,7 +670,7 @@ static void _update_cb(void *data, int action, char const *db_name, char const * if (strcmp(table_name, PREF_TBL_NAME) != 0) { - LOGI("[%s] given table name (%s) is not same", __FUNCTION__, table_name); + SECURE_LOGE("given table name (%s) is not same", table_name); return; } @@ -558,7 +683,7 @@ static void _update_cb(void *data, int action, char const *db_name, char const * sqlite3_free(buf); if (ret != SQLITE_OK) { - LOGI("[%s] fail to read data(%s)", __FUNCTION__, errmsg); + LOGI("fail to read data(%s)", errmsg); sqlite3_free(errmsg); return; } @@ -584,8 +709,8 @@ int preference_remove(const char *key) { int ret; char *buf; - char *errmsg; bool exist; + sqlite3_stmt *stmt; ret = preference_is_existing(key, &exist); if (ret != PREFERENCE_ERROR_NONE) @@ -595,28 +720,53 @@ int preference_remove(const char *key) if (!exist) { - return PREFERENCE_ERROR_NONE; + return PREFERENCE_ERROR_NO_KEY; } /* insert data or update data if data already exist */ - buf = sqlite3_mprintf("DELETE FROM %s WHERE %s = '%s';", + buf = sqlite3_mprintf("DELETE FROM %s WHERE %s = ?", PREF_TBL_NAME, PREF_F_KEY_NAME, key); - if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } - ret = sqlite3_exec(pref_db, buf, NULL, NULL, &errmsg); - sqlite3_free(buf); - if (ret != SQLITE_OK) - { - LOGE("[%s] IO_ERROR(0x%08x) : fail to delete data (%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); - sqlite3_free(errmsg); + ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC); + if(ret != SQLITE_OK) { + LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("IO_ERROR(0x%08x): fail to delete data(%d/%s)", + PREFERENCE_ERROR_IO_ERROR, + sqlite3_extended_errcode(pref_db), + sqlite3_errmsg(pref_db)); + sqlite3_finalize(stmt); return PREFERENCE_ERROR_IO_ERROR; } + sqlite3_finalize(stmt); + if(buf) { + sqlite3_free(buf); + buf = NULL; + } + // if exist, remove changed cb _remove_node(key); @@ -634,7 +784,7 @@ int preference_remove_all(void) { if (_initialize() != PREFERENCE_ERROR_NONE) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to initialize db", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } } @@ -643,7 +793,7 @@ int preference_remove_all(void) buf = sqlite3_mprintf("DELETE FROM %s;", PREF_TBL_NAME); if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } @@ -651,7 +801,7 @@ int preference_remove_all(void) sqlite3_free(buf); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to delete data (%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); + LOGE("IO_ERROR(0x%08x) : fail to delete data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg); sqlite3_free(errmsg); return PREFERENCE_ERROR_IO_ERROR; } @@ -676,7 +826,7 @@ int preference_set_changed_cb(const char *key, preference_changed_cb callback, v if (!exist) { - LOGE("[%s] NO_KEY(0x%08x) : fail to find given key(%s)", __FUNCTION__, PREFERENCE_ERROR_NO_KEY, key); + LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key); return PREFERENCE_ERROR_NO_KEY; } @@ -691,12 +841,19 @@ int preference_set_changed_cb(const char *key, preference_changed_cb callback, v int preference_unset_changed_cb(const char *key) { - if (pref_db == NULL) + int ret; + bool exist; + + ret = preference_is_existing(key, &exist); + if (ret != PREFERENCE_ERROR_NONE) { - if (_initialize() != PREFERENCE_ERROR_NONE) - { - return PREFERENCE_ERROR_IO_ERROR; - } + return ret; + } + + if (!exist) + { + LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key); + return PREFERENCE_ERROR_NO_KEY; } return _remove_node(key); @@ -712,25 +869,25 @@ int preference_foreach_item(preference_item_cb callback, void *user_data) char *errmsg; int i; + if (callback == NULL) + { + LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + if (pref_db == NULL) { if (_initialize() != PREFERENCE_ERROR_NONE) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to initialize db", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } } - if (callback == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, PREFERENCE_ERROR_INVALID_PARAMETER); - return PREFERENCE_ERROR_INVALID_PARAMETER; - } - buf = sqlite3_mprintf("SELECT %s FROM %s;", PREF_F_KEY_NAME, PREF_TBL_NAME); if (buf == NULL) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to create query string", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR); + LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR); return PREFERENCE_ERROR_IO_ERROR; } @@ -738,7 +895,7 @@ int preference_foreach_item(preference_item_cb callback, void *user_data) sqlite3_free(buf); if (ret != SQLITE_OK) { - LOGE("[%s] IO_ERROR(0x%08x) : fail to read data (%s)", __FUNCTION__, PREFERENCE_ERROR_IO_ERROR, errmsg); + LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg); sqlite3_free(errmsg); return PREFERENCE_ERROR_IO_ERROR; } diff --git a/preference/preference_inoti.c b/preference/preference_inoti.c new file mode 100755 index 0000000..7cbffbd --- /dev/null +++ b/preference/preference_inoti.c @@ -0,0 +1,432 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define INOTY_EVENT_MASK (IN_CLOSE_WRITE | IN_DELETE_SELF) + +/* inotify */ +struct noti_node { + int wd; + char *keyname; + preference_changed_cb cb; + void *cb_data; + struct noti_node *next; +}; +typedef struct noti_node noti_node_s; +static GList *g_notilist; + +static int _preference_inoti_comp_with_wd(gconstpointer a, gconstpointer b) +{ + int r; + + noti_node_s *key1 = (noti_node_s *) a; + noti_node_s *key2 = (noti_node_s *) b; + + r = key1->wd - key2->wd; + return r; +} + +static int _kdb_inoti_fd; + +static pthread_mutex_t _kdb_inoti_fd_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _kdb_g_ns_mutex = PTHREAD_MUTEX_INITIALIZER; + +static GSource *_kdb_handler; + +static GList* _preference_copy_noti_list(GList *orig_notilist) +{ + GList *copy_notilist = NULL; + struct noti_node *n = NULL; + struct noti_node *t = NULL; + + if (!orig_notilist) + return NULL; + + orig_notilist = g_list_first(orig_notilist); + if (!orig_notilist) + return NULL; + + while (orig_notilist) { + do { + t = orig_notilist->data; + + if (t == NULL) { + WARN("noti item data is null"); + break; + } + + if ((t->keyname == NULL) || (strlen(t->keyname) == 0)) { + WARN("noti item data key name is null"); + break; + } + + n = calloc(1, sizeof(noti_node_s)); + if (n == NULL) { + ERR("_preference_copy_noti_list : calloc failed. memory full"); + break; + } + + n->keyname = strndup(t->keyname, PREFERENCE_KEY_PATH_LEN); + if (n->keyname == NULL) + { + ERR("The memory is insufficient, errno: %d (%s)", errno, strerror(errno)); + free(n); + break; + } + n->wd = t->wd; + n->cb_data = t->cb_data; + n->cb = t->cb; + + copy_notilist = g_list_append(copy_notilist, n); + } while (0); + + orig_notilist = g_list_next(orig_notilist); + } + return copy_notilist; +} + +static void _preference_free_noti_node(gpointer data) +{ + struct noti_node *n = (struct noti_node*)data; + g_free(n->keyname); + g_free(n); +} + +static void _preference_free_noti_list(GList *noti_list) +{ + g_list_free_full(noti_list, _preference_free_noti_node); +} + + +static gboolean _preference_kdb_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data) +{ + int fd, r, res; + struct inotify_event ie; + GList *l_notilist = NULL; + + fd = g_io_channel_unix_get_fd(src); + r = read(fd, &ie, sizeof(ie)); + + while (r > 0) { + if (ie.mask & INOTY_EVENT_MASK) { + + INFO("read event from GIOChannel. wd : %d", ie.wd); + + pthread_mutex_lock(&_kdb_g_ns_mutex); + l_notilist = _preference_copy_noti_list(g_notilist); + pthread_mutex_unlock(&_kdb_g_ns_mutex); + + if (l_notilist) { + + struct noti_node *t = NULL; + GList *noti_list = NULL; + + noti_list = g_list_first(l_notilist); + + while (noti_list) { + t = noti_list->data; + + keynode_t* keynode = _preference_keynode_new(); + if (keynode == NULL) { + ERR("key malloc fail"); + break; + } + + if ( (t) && (t->wd == ie.wd) && (t->keyname) ) { + + res = _preference_keynode_set_keyname(keynode, t->keyname); + if (res != PREFERENCE_ERROR_NONE) { + ERR("_preference_keynode_set_keyname() failed(%d)", res); + goto out_func; + } + + if ((ie.mask & IN_DELETE_SELF)) + { + res = _preference_kdb_del_notify(keynode); + if (res != PREFERENCE_ERROR_NONE) + ERR("_preference_kdb_del_notify() failed(%d)", res); + } + else + { + res = _preference_get_key(keynode); + if (res != PREFERENCE_ERROR_NONE) + ERR("_preference_get_key() failed(%d)", res); + + INFO("key(%s) is changed. cb(%p) called", t->keyname, t->cb); + t->cb(t->keyname, t->cb_data); + } + } + else if ( (t) && (t->keyname == NULL) ) { /* for debugging */ + ERR("preference keyname is null."); + } +out_func: + _preference_keynode_free(keynode); + + noti_list = g_list_next(noti_list); + } + + _preference_free_noti_list(l_notilist); + } + } + + if (ie.len > 0) + (void) lseek(fd, ie.len, SEEK_CUR); + + r = read(fd, &ie, sizeof(ie)); + } + return TRUE; +} + +static int _preference_kdb_noti_init(void) +{ + GIOChannel *gio; + int ret = 0; + + pthread_mutex_lock(&_kdb_inoti_fd_mutex); + + if (0 < _kdb_inoti_fd) { + ERR("Error: invalid _kdb_inoti_fd"); + pthread_mutex_unlock(&_kdb_inoti_fd_mutex); + return PREFERENCE_ERROR_IO_ERROR; + } + _kdb_inoti_fd = inotify_init(); + if (_kdb_inoti_fd == -1) { + char err_buf[100] = { 0, }; + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("inotify init: %s", err_buf); + pthread_mutex_unlock(&_kdb_inoti_fd_mutex); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = fcntl(_kdb_inoti_fd, F_SETFD, FD_CLOEXEC); + if (ret < 0) { + char err_buf[100] = { 0, }; + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("inotify init: %s", err_buf); + pthread_mutex_unlock(&_kdb_inoti_fd_mutex); + return PREFERENCE_ERROR_IO_ERROR; + } + + ret = fcntl(_kdb_inoti_fd, F_SETFL, O_NONBLOCK); + if (ret < 0) { + char err_buf[100] = { 0, }; + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("inotify init: %s", err_buf); + pthread_mutex_unlock(&_kdb_inoti_fd_mutex); + return PREFERENCE_ERROR_IO_ERROR; + } + + pthread_mutex_unlock(&_kdb_inoti_fd_mutex); + + gio = g_io_channel_unix_new(_kdb_inoti_fd); + retvm_if(gio == NULL, -1, "Error: create a new GIOChannel"); + + g_io_channel_set_flags(gio, G_IO_FLAG_NONBLOCK, NULL); + + _kdb_handler = g_io_create_watch(gio, G_IO_IN); + g_source_set_callback(_kdb_handler, (GSourceFunc) _preference_kdb_gio_cb, NULL, NULL); + g_source_attach(_kdb_handler, NULL); + g_io_channel_unref(gio); + g_source_unref(_kdb_handler); + + return PREFERENCE_ERROR_NONE; +} + +int _preference_kdb_add_notify(keynode_t *keynode, preference_changed_cb cb, void *data) +{ + char path[PATH_MAX]; + int wd; + struct noti_node t, *n, *node; + char err_buf[ERR_LEN] = { 0, }; + int ret = 0; + GList *list = NULL; + int func_ret = PREFERENCE_ERROR_NONE; + char *keyname = keynode->keyname; + + retvm_if((keyname == NULL || cb == NULL), PREFERENCE_ERROR_INVALID_PARAMETER, + "_preference_kdb_add_notify : Invalid argument - keyname(%s) cb(%p)", + keyname, cb); + + if (_kdb_inoti_fd <= 0) + if (_preference_kdb_noti_init()) + return PREFERENCE_ERROR_IO_ERROR; + + ret = _preference_get_key_path(keynode, path); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("Invalid argument: key is not valid"); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + + if (0 != access(path, F_OK)) { + if (errno == ENOENT) { + ERR("_preference_kdb_add_notify : Key(%s) does not exist", keyname); + return PREFERENCE_ERROR_IO_ERROR; + } + } + + wd = inotify_add_watch(_kdb_inoti_fd, path, INOTY_EVENT_MASK); + if (wd == -1) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("_preference_kdb_add_notify : add noti(%s)", err_buf); + return PREFERENCE_ERROR_IO_ERROR; + } + + t.wd = wd; + + pthread_mutex_lock(&_kdb_g_ns_mutex); + + list = g_list_find_custom(g_notilist, &t, (GCompareFunc)_preference_inoti_comp_with_wd); + if (list) { + WARN("_preference_kdb_add_notify : key(%s) change callback(%p)", keyname, cb); + + node = list->data; + node->wd = wd; + node->cb_data = data; + node->cb = cb; + + goto out_func; + } + + n = calloc(1, sizeof(noti_node_s)); + if (n == NULL) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("_preference_kdb_add_notify : add noti(%s)", err_buf); + func_ret = PREFERENCE_ERROR_IO_ERROR; + goto out_func; + } + + n->keyname = strndup(keyname, PREFERENCE_KEY_PATH_LEN); + if (n->keyname == NULL) { + ERR("The memory is insufficient, errno: %d (%s)", errno, strerror(errno)); + free(n); + goto out_func; + } + n->wd = wd; + n->cb_data = data; + n->cb = cb; + + g_notilist = g_list_append(g_notilist, n); + if (!g_notilist) { + ERR("g_list_append fail"); + } + + INFO("cb(%p) is added for %s. tot cb cnt : %d\n", cb, n->keyname, g_list_length(g_notilist)); + +out_func: + pthread_mutex_unlock(&_kdb_g_ns_mutex); + + return func_ret; +} + +int _preference_kdb_del_notify(keynode_t *keynode) +{ + int wd = 0; + int r = 0; + struct noti_node *n = NULL; + struct noti_node t; + char path[PATH_MAX] = { 0, }; + char err_buf[ERR_LEN] = { 0, }; + int del = 0; + int ret = 0; + char *keyname = keynode->keyname; + int func_ret = PREFERENCE_ERROR_NONE; + GList *noti_list; + + retvm_if(keyname == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: keyname(%s)", keyname); + + ret = _preference_get_key_path(keynode, path); + if (ret != PREFERENCE_ERROR_NONE) { + ERR("Invalid argument: key is not valid"); + return PREFERENCE_ERROR_INVALID_PARAMETER; + } + + if (0 != access(path, F_OK)) { + if (errno == ENOENT) { + ERR("_preference_kdb_del_notify : Key(%s) does not exist", keyname); + return PREFERENCE_ERROR_IO_ERROR; + } + } + + retvm_if(_kdb_inoti_fd == 0, PREFERENCE_ERROR_NONE, "Invalid operation: not exist anything for inotify"); + + /* get wd */ + wd = inotify_add_watch(_kdb_inoti_fd, path, INOTY_EVENT_MASK); + if (wd == -1) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("Error: inotify_add_watch() [%s]: %s", path, err_buf); + return PREFERENCE_ERROR_IO_ERROR; + } + + pthread_mutex_lock(&_kdb_g_ns_mutex); + + t.wd = wd; + + noti_list = g_list_find_custom(g_notilist, &t, (GCompareFunc)_preference_inoti_comp_with_wd); + if(noti_list) { + del++; + + n = noti_list->data; + g_notilist = g_list_remove(g_notilist, n); + g_free(n->keyname); + g_free(n); + + r = inotify_rm_watch(_kdb_inoti_fd, wd); + if(r == -1) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ERR("Error: inotify_rm_watch [%s]: %s", keyname, err_buf); + func_ret = PREFERENCE_ERROR_IO_ERROR; + } + + INFO("key(%s) cb is removed. remained noti list total length(%d)", + keyname, g_list_length(g_notilist)); + } + + if(g_list_length(g_notilist) == 0) { + close(_kdb_inoti_fd); + _kdb_inoti_fd = 0; + + g_source_destroy(_kdb_handler); + _kdb_handler = NULL; + + g_list_free(g_notilist); + g_notilist = NULL; + + INFO("all noti list is freed"); + } + + pthread_mutex_unlock(&_kdb_g_ns_mutex); + + if(del == 0) { + errno = ENOENT; + func_ret = PREFERENCE_ERROR_IO_ERROR; + } + + return func_ret; +} diff --git a/src/app_device.c b/src/app_device.c index 936b625..17917b0 100755 --- a/src/app_device.c +++ b/src/app_device.c @@ -11,62 +11,11 @@ * 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. + * limitations under the License. */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_APPLICATION" - -app_device_orientation_e app_convert_appcore_rm(enum appcore_rm rm) -{ - app_device_orientation_e dev_orientation; - - switch (rm) - { - case APPCORE_RM_PORTRAIT_NORMAL: - dev_orientation = APP_DEVICE_ORIENTATION_0; - break; - - case APPCORE_RM_PORTRAIT_REVERSE: - dev_orientation = APP_DEVICE_ORIENTATION_180; - break; - - case APPCORE_RM_LANDSCAPE_NORMAL: - dev_orientation = APP_DEVICE_ORIENTATION_270; - break; - - case APPCORE_RM_LANDSCAPE_REVERSE: - dev_orientation = APP_DEVICE_ORIENTATION_90; - break; - - default: - dev_orientation = APP_DEVICE_ORIENTATION_0; - break; - } - - return dev_orientation; -} +#include app_device_orientation_e app_get_device_orientation(void) { diff --git a/src/app_main.c b/src/app_main.c index 058607f..78e4f2b 100755 --- a/src/app_main.c +++ b/src/app_main.c @@ -11,34 +11,30 @@ * 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. + * limitations under the License. */ -#include #include -#include -#include -#include -#include -#include #include #include #include -#include #include +#include #include +#include -#include -#include +#include +#include +#include #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "TIZEN_N_APPLICATION" +#define LOG_TAG "CAPI_APPFW_APPLICATION" typedef enum { APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated @@ -62,15 +58,19 @@ static int app_appcore_resume(void *data); static int app_appcore_terminate(void *data); static int app_appcore_reset(bundle *appcore_bundle, void *data); -static int app_appcore_low_memory(void *data); -static int app_appcore_low_battery(void *data); -static int app_appcore_rotation_event(enum appcore_rm rm, void *data); -static int app_appcore_lang_changed(void *data); -static int app_appcore_region_changed(void *data); +static int app_appcore_low_memory(void *event, void *data); +static int app_appcore_low_battery(void *event, void *data); +static int app_appcore_rotation_event(void *event, enum appcore_rm rm, void *data); +static int app_appcore_lang_changed(void *event, void *data); +static int app_appcore_region_changed(void *event, void *data); static void app_set_appcore_event_cb(app_context_h app_context); static void app_unset_appcore_event_cb(void); +int app_main(int argc, char **argv, app_event_callback_s *callback, void *user_data) +{ + return app_efl_main(&argc, &argv, callback, user_data); +} int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data) { @@ -106,18 +106,20 @@ int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void * return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL); } - if (app_get_package(&(app_context.package)) != APP_ERROR_NONE) + if (app_get_id(&(app_context.package)) != APP_ERROR_NONE) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); } - + if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE) { + free(app_context.package); return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name"); } app_context.state = APP_STATE_CREATING; + LOGI("app_efl_main"); appcore_efl_main(app_context.app_name, argc, argv, &appcore_context); free(app_context.package); @@ -126,18 +128,23 @@ int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void * return APP_ERROR_NONE; } +void app_exit(void) +{ + app_efl_exit(); +} void app_efl_exit(void) { + LOGI("app_efl_exit"); elm_exit(); } int app_appcore_create(void *data) { + LOGI("app_appcore_create"); app_context_h app_context = data; app_create_cb create_cb; - char locale_dir[TIZEN_PATH_MAX] = {0, }; if (app_context == NULL) { @@ -146,12 +153,6 @@ int app_appcore_create(void *data) app_set_appcore_event_cb(app_context); - snprintf(locale_dir, TIZEN_PATH_MAX, PATH_FMT_LOCALE_DIR, app_context->package); - if (access(locale_dir, R_OK) != 0) { - snprintf(locale_dir, TIZEN_PATH_MAX, PATH_FMT_RO_LOCALE_DIR, app_context->package); - } - appcore_set_i18n(app_context->app_name, locale_dir); - create_cb = app_context->callback->create; if (create_cb == NULL || create_cb(app_context->data) == false) @@ -166,6 +167,7 @@ int app_appcore_create(void *data) int app_appcore_terminate(void *data) { + LOGI("app_appcore_terminate"); app_context_h app_context = data; app_terminate_cb terminate_cb; @@ -181,7 +183,7 @@ int app_appcore_terminate(void *data) terminate_cb(app_context->data); } - app_unset_appcore_event_cb(); + app_unset_appcore_event_cb(); app_finalizer_execute(); @@ -190,6 +192,7 @@ int app_appcore_terminate(void *data) int app_appcore_pause(void *data) { + LOGI("app_appcore_pause"); app_context_h app_context = data; app_pause_cb pause_cb; @@ -210,6 +213,7 @@ int app_appcore_pause(void *data) int app_appcore_resume(void *data) { + LOGI("app_appcore_resume"); app_context_h app_context = data; app_resume_cb resume_cb; @@ -231,35 +235,37 @@ int app_appcore_resume(void *data) int app_appcore_reset(bundle *appcore_bundle, void *data) { + LOGI("app_appcore_reset"); app_context_h app_context = data; - app_service_cb service_cb; - service_h service; + app_control_cb callback; + app_control_h app_control; if (app_context == NULL) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); } - if (service_create_event(appcore_bundle, &service) != APP_ERROR_NONE) + if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE) { - return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a service handle from the bundle"); + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a app_control handle from the bundle"); } - service_cb = app_context->callback->service; + callback = app_context->callback->app_control; - if (service_cb != NULL) + if (callback != NULL) { - service_cb(service, app_context->data); + callback(app_control, app_context->data); } - service_destroy(service); + app_control_destroy(app_control); return APP_ERROR_NONE; } - -int app_appcore_low_memory(void *data) +int app_appcore_low_memory(void *event_info, void *data) { + LOGI("app_appcore_low_memory"); + app_context_h app_context = data; app_low_memory_cb low_memory_cb; @@ -278,11 +284,13 @@ int app_appcore_low_memory(void *data) return APP_ERROR_NONE; } -int app_appcore_low_battery(void *data) +int app_appcore_low_battery(void *event_info, void *data) { app_context_h app_context = data; app_low_battery_cb low_battery_cb; + LOGI("app_appcore_low_battery"); + if (app_context == NULL) { return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); @@ -292,14 +300,16 @@ int app_appcore_low_battery(void *data) if (low_battery_cb != NULL) { + LOGI("app_appcore_low_memory: app_appcore_low_memory_cb() is called"); low_battery_cb(app_context->data); } return APP_ERROR_NONE; } -int app_appcore_rotation_event(enum appcore_rm rm, void *data) +int app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data) { + LOGI("app_appcore_rotation_event"); app_context_h app_context = data; app_device_orientation_cb device_orientation_cb; @@ -322,8 +332,9 @@ int app_appcore_rotation_event(enum appcore_rm rm, void *data) return APP_ERROR_NONE; } -int app_appcore_lang_changed(void *data) +int app_appcore_lang_changed(void *event_info, void *data) { + LOGI("app_appcore_lang_changed"); app_context_h app_context = data; app_language_changed_cb lang_changed_cb; @@ -342,8 +353,9 @@ int app_appcore_lang_changed(void *data) return APP_ERROR_NONE; } -int app_appcore_region_changed(void *data) +int app_appcore_region_changed(void *event_info, void *data) { + LOGI("app_appcore_region_changed"); app_context_h app_context = data; app_region_format_changed_cb region_changed_cb; @@ -399,3 +411,378 @@ void app_unset_appcore_event_cb(void) appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL); appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL); } + +#define UI_APP_EVENT_MAX 5 +static Eina_List *handler_list[UI_APP_EVENT_MAX] = {NULL, }; +static int handler_initialized = 0; +static int appcore_initialized = 0; + +struct ui_app_context { + char *package; + char *app_name; + app_state_e state; + ui_app_lifecycle_callback_s *callback; + void *data; +}; + +static void _free_handler_list(void) +{ + int i; + app_event_handler_h handler; + + for (i = 0; i < UI_APP_EVENT_MAX; i++) { + EINA_LIST_FREE(handler_list[i], handler) + free(handler); + } + + eina_shutdown(); +} + +static int _ui_app_appcore_low_memory(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; + + LOGI("_app_appcore_low_memory"); + + event.type = APP_EVENT_LOW_MEMORY; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_MEMORY], l, handler) { + handler->cb(&event, handler->data); + } + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_low_battery(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; + + LOGI("_ui_app_appcore_low_battery"); + + event.type = APP_EVENT_LOW_BATTERY; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_LOW_BATTERY], l, handler) { + handler->cb(&event, handler->data); + } + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_rotation_event(void *event_info, enum appcore_rm rm, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; + + LOGI("_ui_app_appcore_rotation_event"); + + event.type = APP_EVENT_DEVICE_ORIENTATION_CHANGED; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED], l, handler) { + handler->cb(&event, handler->data); + } + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_lang_changed(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; + + LOGI("_ui_app_appcore_lang_changed"); + + event.type = APP_EVENT_LANGUAGE_CHANGED; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_LANGUAGE_CHANGED], l, handler) { + handler->cb(&event, handler->data); + } + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_region_changed(void *event_info, void *data) +{ + Eina_List *l; + app_event_handler_h handler; + struct app_event_info event; + + if (event_info == NULL) { + LOGI("receive empty event, ignore it"); + return APP_ERROR_NONE; + } + + LOGI("_ui_app_appcore_region_changed"); + + event.type = APP_EVENT_REGION_FORMAT_CHANGED; + event.value = event_info; + + EINA_LIST_FOREACH(handler_list[APP_EVENT_REGION_FORMAT_CHANGED], l, handler) { + handler->cb(&event, handler->data); + } + + return APP_ERROR_NONE; +} + + +static void _ui_app_set_appcore_event_cb(void) +{ + appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, _ui_app_appcore_low_memory, NULL); + appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, _ui_app_appcore_low_battery, NULL); + if (eina_list_count(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED]) > 0) + appcore_set_rotation_cb(_ui_app_appcore_rotation_event, NULL); + appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, _ui_app_appcore_lang_changed, NULL); + appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, _ui_app_appcore_region_changed, NULL); +} + +static void _ui_app_unset_appcore_event_cb(void) +{ + appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL); + appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, NULL, NULL); + if (eina_list_count(handler_list[APP_EVENT_DEVICE_ORIENTATION_CHANGED]) > 0) + appcore_unset_rotation_cb(); + appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL); + appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL); +} + +static int _ui_app_appcore_create(void *data) +{ + LOGI("app_appcore_create"); + struct ui_app_context *app_context = data; + app_create_cb create_cb; + + if (app_context == NULL) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + + appcore_initialized = 1; + _ui_app_set_appcore_event_cb(); + + create_cb = app_context->callback->create; + + if (create_cb == NULL || create_cb(app_context->data) == false) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false"); + + app_context->state = APP_STATE_RUNNING; + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_terminate(void *data) +{ + LOGI("app_appcore_terminate"); + struct ui_app_context *app_context = data; + app_terminate_cb terminate_cb; + + if (app_context == NULL) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + + terminate_cb = app_context->callback->terminate; + + if (terminate_cb != NULL) + terminate_cb(app_context->data); + + _ui_app_unset_appcore_event_cb(); + + app_finalizer_execute(); + + if (handler_initialized) { + _free_handler_list(); + handler_initialized = 0; + } + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_pause(void *data) +{ + LOGI("app_appcore_pause"); + struct ui_app_context *app_context = data; + app_pause_cb pause_cb; + + if (app_context == NULL) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + + pause_cb = app_context->callback->pause; + + if (pause_cb != NULL) + pause_cb(app_context->data); + + return APP_ERROR_NONE; +} + +static int _ui_app_appcore_resume(void *data) +{ + LOGI("app_appcore_resume"); + struct ui_app_context *app_context = data; + app_resume_cb resume_cb; + + if (app_context == NULL) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + + resume_cb = app_context->callback->resume; + + if (resume_cb != NULL) + resume_cb(app_context->data); + + return APP_ERROR_NONE; +} + + +static int _ui_app_appcore_reset(bundle *appcore_bundle, void *data) +{ + LOGI("app_appcore_reset"); + struct ui_app_context *app_context = data; + app_control_cb callback; + app_control_h app_control; + + if (app_context == NULL) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL); + + if (app_control_create_event(appcore_bundle, &app_control) != APP_ERROR_NONE) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a app_control handle from the bundle"); + + callback = app_context->callback->app_control; + + if (callback != NULL) + callback(app_control, app_context->data); + + app_control_destroy(app_control); + + return APP_ERROR_NONE; +} + +int ui_app_main(int argc, char **argv, ui_app_lifecycle_callback_s *callback, void *user_data) +{ + struct ui_app_context app_context = { + .package = NULL, + .app_name = NULL, + .state = APP_STATE_NOT_RUNNING, + .callback = callback, + .data = user_data + }; + + struct appcore_ops appcore_context = { + .data = &app_context, + .create = _ui_app_appcore_create, + .terminate = _ui_app_appcore_terminate, + .pause = _ui_app_appcore_pause, + .resume = _ui_app_appcore_resume, + .reset = _ui_app_appcore_reset, + }; + + if (argc < 1 || argv == NULL || callback == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (callback->create == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "app_create_cb() callback must be registered"); + + if (app_context.state != APP_STATE_NOT_RUNNING) + return app_error(APP_ERROR_ALREADY_RUNNING, __FUNCTION__, NULL); + + if (app_get_id(&(app_context.package)) != APP_ERROR_NONE) + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); + + if (app_get_package_app_name(app_context.package, &(app_context.app_name)) != APP_ERROR_NONE) { + free(app_context.package); + return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name"); + } + + app_context.state = APP_STATE_CREATING; + + LOGI("app_efl_main"); + appcore_efl_main(app_context.app_name, &argc, &argv, &appcore_context); + + free(app_context.package); + free(app_context.app_name); + + return APP_ERROR_NONE; +} + +void ui_app_exit(void) +{ + app_efl_exit(); +} + +int ui_app_add_event_handler(app_event_handler_h *event_handler, app_event_type_e event_type, app_event_cb callback, void *user_data) +{ + app_event_handler_h handler; + Eina_List *l_itr; + + if (!handler_initialized) { + eina_init(); + handler_initialized = 1; + } + + if (event_handler == NULL || callback == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "null parameter"); + + if (event_type < APP_EVENT_LOW_MEMORY || event_type > APP_EVENT_REGION_FORMAT_CHANGED) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid event type"); + + EINA_LIST_FOREACH(handler_list[event_type], l_itr, handler) { + if (handler->cb == callback) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "already registered"); + } + + handler = calloc(1, sizeof(struct app_event_handler)); + if (!handler) + return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler"); + + handler->type = event_type; + handler->cb = callback; + handler->data = user_data; + + if (appcore_initialized && event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED + && eina_list_count(handler_list[event_type]) == 0) + appcore_set_rotation_cb(_ui_app_appcore_rotation_event, NULL); + + handler_list[event_type] = eina_list_append(handler_list[event_type], handler); + + *event_handler = handler; + + return APP_ERROR_NONE; +} + +int ui_app_remove_event_handler(app_event_handler_h event_handler) +{ + app_event_handler_h handler; + app_event_type_e type; + Eina_List *l_itr; + Eina_List *l_next; + + if (event_handler == NULL) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "handler is null"); + + if (!handler_initialized) { + LOGI("handler list is not initialized"); + return APP_ERROR_NONE; + } + + type = event_handler->type; + if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_REGION_FORMAT_CHANGED) + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid handler"); + + EINA_LIST_FOREACH_SAFE(handler_list[type], l_itr, l_next, handler) { + if (handler == event_handler) { + free(handler); + handler_list[type] = eina_list_remove_list(handler_list[type], l_itr); + + if (appcore_initialized && type == APP_EVENT_DEVICE_ORIENTATION_CHANGED + && eina_list_count(handler_list[type]) == 0) + appcore_unset_rotation_cb(); + + return APP_ERROR_NONE; + } + } + + return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "cannot find such handler"); +} diff --git a/src/app_resource.c b/src/app_resource.c index 219eb6c..5c8dc29 100755 --- a/src/app_resource.c +++ b/src/app_resource.c @@ -11,186 +11,44 @@ * 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. + * limitations under the License. */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include #include #include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_APPLICATION" - -static const char *INSTALLED_PATH = "/opt/apps"; -static const char *RO_INSTALLED_PATH = "/usr/apps"; -static const char *RES_DIRECTORY_NAME = "res"; -static const char *DATA_DIRECTORY_NAME = "data"; - -static char * app_get_root_directory(char *buffer, int size) -{ - char *package = NULL; - char root_directory[TIZEN_PATH_MAX] = {0, }; - char bin_directory[TIZEN_PATH_MAX] = {0, }; - - if (app_get_package(&package) != APP_ERROR_NONE) - { - app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); - return NULL; - } - - snprintf(root_directory, sizeof(root_directory), "%s/%s", INSTALLED_PATH, package); - snprintf(bin_directory, sizeof(bin_directory), "%s/bin", root_directory); - - if (access(bin_directory, R_OK) != 0) { - snprintf(root_directory, sizeof(root_directory), "%s/%s", RO_INSTALLED_PATH, package); - } - - free(package); - - if (size < strlen(root_directory)+1) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "the buffer is not big enough"); - return NULL; - } - snprintf(buffer, size, "%s", root_directory); - - return buffer; -} - -static char* app_get_resource_directory(char *buffer, int size) +void app_set_reclaiming_system_cache_on_pause(bool enable) { - char root_directory[TIZEN_PATH_MAX] = {0, }; - char resource_directory[TIZEN_PATH_MAX] = {0, }; - - if (app_get_root_directory(root_directory, sizeof(root_directory)) == NULL) - { - app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the root directory of the application"); - return NULL; - } - - snprintf(resource_directory, sizeof(resource_directory), "%s/%s", root_directory, RES_DIRECTORY_NAME); - - if (size < strlen(resource_directory) +1) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "the buffer is not big enough"); - return NULL; - } - - snprintf(buffer, size, "%s", resource_directory); - - return buffer; + appcore_set_system_resource_reclaiming(enable); } -char* app_get_data_directory(char *buffer, int size) +//#ifdef _APPFW_FEATURE_PROCESS_POOL +void* app_get_preinitialized_window(const char *win_name) { - static char data_directory[TIZEN_PATH_MAX] = {0, }; - static int data_directory_length = 0; - - if (data_directory[0] == '\0') - { - char *root_directory = NULL; - char *package = NULL; - - root_directory = calloc(1, TIZEN_PATH_MAX); - - if (root_directory == NULL) - { - app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - return NULL; - } - - if (app_get_package(&package) != APP_ERROR_NONE) - { - app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package"); - return NULL; - } - - snprintf(root_directory, TIZEN_PATH_MAX, "%s/%s", INSTALLED_PATH, package); - - free(package); - - snprintf(data_directory, sizeof(data_directory), "%s/%s", root_directory, DATA_DIRECTORY_NAME); - - data_directory_length = strlen(data_directory); - - free(root_directory); - } - - if (size < data_directory_length+1) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "the buffer is not big enough"); - return NULL; - } - - snprintf(buffer, size, "%s", data_directory); - - return buffer; +#ifdef _APPFW_FEATURE_PROCESS_POOL + appcore_set_preinit_window_name(win_name); + return aul_get_preinit_window(win_name); +#else + return NULL; +#endif } -char* app_get_resource(const char *resource, char *buffer, int size) +void* app_get_preinitialized_background(void) { - static char resource_directory[TIZEN_PATH_MAX] = {0, }; - static int resource_directory_length = 0; - - int resource_path_length = 0; - - if (resource == NULL) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - return NULL; - } - - if (buffer == NULL || size <= 0) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - return NULL; - } - - if (resource_directory[0] == '\0') - { - if (app_get_resource_directory(resource_directory, sizeof(resource_directory)) == NULL) - { - app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the path to the resource directory"); - return NULL; - } - - resource_directory_length = strlen(resource_directory); - } - - resource_path_length = resource_directory_length + strlen("/") + strlen(resource); - - if (size < resource_path_length+1) - { - app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "the buffer is not big enough"); - return NULL; - } - - snprintf(buffer, size, "%s/%s", resource_directory, resource); - - return buffer; +#ifdef _APPFW_FEATURE_PROCESS_POOL + return aul_get_preinit_background(); +#else + return NULL; +#endif } - -void app_set_reclaiming_system_cache_on_pause(bool enable) +void* app_get_preinitialized_conformant(void) { - appcore_set_system_resource_reclaiming(enable); +#ifdef _APPFW_FEATURE_PROCESS_POOL + return aul_get_preinit_conformant(); +#else + return NULL; +#endif } - +//#endif diff --git a/src/i18n.c b/src/i18n.c index a1ca9e3..6e5609f 100755 --- a/src/i18n.c +++ b/src/i18n.c @@ -15,13 +15,8 @@ */ -#include -#include -#include #include -#include - char* i18n_get_text(const char *message) { return gettext(message); diff --git a/src/service.c b/src/service.c deleted file mode 100755 index c44e171..0000000 --- a/src/service.c +++ /dev/null @@ -1,1232 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_SERVICE" - -#ifndef TIZEN_PATH_MAX -#define TIZEN_PATH_MAX 1024 -#endif - -#define BUNDLE_KEY_PREFIX_AUL "__AUL_" -#define BUNDLE_KEY_PREFIX_SERVICE "__APP_SVC_" - -#define BUNDLE_KEY_OPERATION "__APP_SVC_OP_TYPE__" -#define BUNDLE_KEY_URI "__APP_SVC_URI__" -#define BUNDLE_KEY_MIME "__APP_SVC_MIME_TYPE__" -#define BUNDLE_KEY_DATA "__APP_SVC_DATA__" -#define BUNDLE_KEY_PACKAGE "__APP_SVC_PKG_NAME__" -#define BUNDLE_KEY_WINDOW "__APP_SVC_K_WIN_ID__" - - -typedef enum { - SERVICE_TYPE_REQUEST, - SERVICE_TYPE_EVENT, - SERVICE_TYPE_REPLY, -} service_type_e; - -struct service_s { - int id; - service_type_e type; - bundle *data; -}; - -typedef struct service_request_context_s { - service_h service; - service_reply_cb reply_cb; - void *user_data; -} *service_request_context_h; - -extern int appsvc_allow_transient_app(bundle *b, unsigned int id); - -static int service_create_reply(bundle *data, struct service_s **service); - -static const char* service_error_to_string(service_error_e error) -{ - switch (error) - { - case SERVICE_ERROR_NONE: - return "NONE"; - - case SERVICE_ERROR_INVALID_PARAMETER: - return "INVALID_PARAMETER"; - - case SERVICE_ERROR_OUT_OF_MEMORY: - return "OUT_OF_MEMORY"; - - case SERVICE_ERROR_APP_NOT_FOUND: - return "APP_NOT_FOUND"; - - case SERVICE_ERROR_KEY_NOT_FOUND: - return "KEY_NOT_FOUND"; - - case SERVICE_ERROR_KEY_REJECTED: - return "KEY_REJECTED"; - - case SERVICE_ERROR_INVALID_DATA_TYPE: - return "INVALID_DATA_TYPE"; - - default : - return "UNKNOWN"; - } -} - -int service_error(service_error_e error, const char* function, const char *description) -{ - if (description) - { - LOGE("[%s] %s(0x%08x) : %s", function, service_error_to_string(error), error, description); - } - else - { - LOGE("[%s] %s(0x%08x)", function, service_error_to_string(error), error); - } - - return error; -} - -static int service_validate_extra_data(const char *data) -{ - if (data == NULL || data[0] == '\0') - { - return SERVICE_ERROR_INVALID_PARAMETER; - } - - return SERVICE_ERROR_NONE; -} - -static int service_valiate_service(service_h service) -{ - if (service == NULL || service->data == NULL) - { - return SERVICE_ERROR_INVALID_PARAMETER; - } - - return SERVICE_ERROR_NONE; -} - -static int service_new_id() -{ - static int sid = 0; - return sid++; -} - -int service_validate_internal_key(const char *key) -{ - if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0) - { - return -1; - } - - if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0) - { - return -1; - } - - return 0; -} - -static void service_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data) -{ - service_request_context_h request_context; - service_h request; - service_h reply = NULL; - service_result_e result; - void *user_data; - service_reply_cb reply_cb; - - if (appsvc_data == NULL) - { - service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service reply"); - return; - } - - if (service_create_reply(appsvc_bundle, &reply) != 0) - { - service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create service reply"); - return; - } - - request_context = appsvc_data; - request = request_context->service; - - switch (appsvc_result) - { - case APPSVC_RES_OK: - result = SERVICE_RESULT_SUCCEEDED; - break; - - case APPSVC_RES_NOT_OK: - result = SERVICE_RESULT_FAILED; - break; - - case APPSVC_RES_CANCEL: - result = SERVICE_RESULT_CANCELED; - break; - - default: - result = SERVICE_RESULT_CANCELED; - break; - } - - user_data = request_context->user_data; - reply_cb = request_context->reply_cb; - - if (reply_cb != NULL) - { - reply_cb(request, reply, result, user_data); - } - else - { - service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback "); - } - - service_destroy(reply); - - if (request_context->service != NULL) - { - service_destroy(request_context->service); - } - - free(request_context); -} - - -int service_create(service_h *service) -{ - return service_create_request(NULL, service); -} - -int service_create_request(bundle *data, service_h *service) -{ - struct service_s *service_request; - - if (service == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - service_request = malloc(sizeof(struct service_s)); - - if (service_request == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle"); - } - - service_request->type = SERVICE_TYPE_REQUEST; - - if (data != NULL) - { - service_request->data = bundle_dup(data); - } - else - { - service_request->data = bundle_create(); - } - - if (service_request->data == NULL) - { - free(service_request); - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle"); - } - - service_request->id = service_new_id(); - - *service = service_request; - - return SERVICE_ERROR_NONE; -} - -int service_create_event(bundle *data, struct service_s **service) -{ - struct service_s *service_event; - - const char *operation; - - if (data == NULL || service == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - service_event = malloc(sizeof(struct service_s)); - - if (service_event == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle"); - } - - service_event->type = SERVICE_TYPE_EVENT; - service_event->data = bundle_dup(data); - service_event->id = service_new_id(); - - operation = appsvc_get_operation(service_event->data); - - if (operation == NULL) - { - appsvc_set_operation(service_event->data, SERVICE_OPERATION_DEFAULT); - } - - *service = service_event; - - return SERVICE_ERROR_NONE; -} - -static int service_create_reply(bundle *data, struct service_s **service) -{ - struct service_s *service_reply; - - if (data == NULL || service == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - service_reply = malloc(sizeof(struct service_s)); - - if (service_reply == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle"); - } - - service_reply->type = SERVICE_TYPE_REPLY; - service_reply->data = bundle_dup(data); - service_reply->id = service_new_id(); - - *service = service_reply; - - return SERVICE_ERROR_NONE; -} - -int service_destroy(service_h service) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - bundle_free(service->data); - service->data = NULL; - free(service); - - return SERVICE_ERROR_NONE; -} - -int service_to_bundle(service_h service, bundle **data) -{ - if (service_valiate_service(service) || data == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - *data = service->data; - - return SERVICE_ERROR_NONE; -} - -int service_set_operation(service_h service, const char *operation) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (operation != NULL) - { - if (appsvc_set_operation(service->data, operation) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation"); - } - } - else - { - bundle_del(service->data, BUNDLE_KEY_OPERATION); - } - - return SERVICE_ERROR_NONE; -} - -int service_get_operation(service_h service, char **operation) -{ - const char *operation_value; - - if (service_valiate_service(service) || operation == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - operation_value = appsvc_get_operation(service->data); - - if (operation_value != NULL) - { - *operation = strdup(operation_value); - } - else - { - *operation = NULL; - } - - return SERVICE_ERROR_NONE; -} - - -int service_set_uri(service_h service, const char *uri) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (uri != NULL) - { - if (appsvc_set_uri(service->data, uri) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI"); - } - } - else - { - bundle_del(service->data, BUNDLE_KEY_URI); - } - - return SERVICE_ERROR_NONE; -} - - -int service_get_uri(service_h service, char **uri) -{ - const char *uri_value; - - if (service_valiate_service(service) || uri == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - uri_value = appsvc_get_uri(service->data); - - if (uri_value != NULL) - { - *uri = strdup(uri_value); - } - else - { - *uri = NULL; - } - - return SERVICE_ERROR_NONE; -} - - -int service_set_mime(service_h service, const char *mime) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (mime != NULL) - { - if (appsvc_set_mime(service->data, mime) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type"); - } - } - else - { - bundle_del(service->data, BUNDLE_KEY_MIME); - } - - return SERVICE_ERROR_NONE; -} - - -int service_get_mime(service_h service, char **mime) -{ - const char *mime_value; - - if (service_valiate_service(service) || mime == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - mime_value = appsvc_get_mime(service->data); - - if (mime_value != NULL) - { - *mime = strdup(mime_value); - } - else - { - *mime = NULL; - } - - return SERVICE_ERROR_NONE; -} - - -int service_set_package(service_h service, const char *package) -{ - // TODO: this function must be deprecated - return service_set_app_id(service, package); -} - -int service_get_package(service_h service, char **package) -{ - // TODO: this function must be deprecated - return service_get_app_id(service, package); -} - - -int service_set_app_id(service_h service, const char *app_id) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (app_id != NULL) - { - if (appsvc_set_pkgname(service->data, app_id) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID"); - } - } - else - { - bundle_del(service->data, BUNDLE_KEY_PACKAGE); - } - - return SERVICE_ERROR_NONE; -} - - -int service_get_app_id(service_h service, char **app_id) -{ - const char *app_id_value; - - if (service_valiate_service(service) || app_id == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - app_id_value = appsvc_get_pkgname(service->data); - - if (app_id_value != NULL) - { - *app_id = strdup(app_id_value); - } - else - { - *app_id = NULL; - } - - return SERVICE_ERROR_NONE; -} - -int service_set_window(service_h service, unsigned int id) -{ - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (id > 0) - { - if (appsvc_allow_transient_app(service->data, id) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id"); - } - } - else - { - bundle_del(service->data, BUNDLE_KEY_WINDOW); - } - - return SERVICE_ERROR_NONE; -} - -int service_get_window(service_h service, unsigned int *id) -{ - const char *window_id; - - if (service_valiate_service(service) || id == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - window_id = bundle_get_val(service->data, BUNDLE_KEY_WINDOW); - - if (window_id != NULL) - { - *id = atoi(window_id); - } - else - { - *id = 0; - } - - return SERVICE_ERROR_NONE; -} - -int service_clone(service_h *clone, service_h service) -{ - service_h service_clone; - - if (service_valiate_service(service) || clone == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - service_clone = malloc(sizeof(struct service_s)); - - if (service_clone == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a service handle"); - } - - service_clone->id = service_new_id(); - service_clone->type = service->type; - service_clone->data = bundle_dup(service->data); - - *clone = service_clone; - - return SERVICE_ERROR_NONE; -} - - -int service_send_launch_request(service_h service, service_reply_cb callback, void *user_data) -{ - const char *operation; - const char *uri; - const char *mime; - const char *package; - - bool implicit_default_operation = false; - int launch_pid; - - service_request_context_h request_context = NULL; - - if (service_valiate_service(service)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - operation = appsvc_get_operation(service->data); - - if (operation == NULL) - { - implicit_default_operation = true; - operation = SERVICE_OPERATION_DEFAULT; - } - - uri = appsvc_get_uri(service->data); - mime = appsvc_get_mime(service->data); - package = appsvc_get_pkgname(service->data); - - // operation : default - if (!strcmp(operation, SERVICE_OPERATION_DEFAULT)) - { - if (package == NULL) - { - return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value"); - } - } - - if (callback != NULL) - { - service_h request_clone = NULL; - - request_context = calloc(1, sizeof(struct service_request_context_s)); - - if (request_context == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - } - - request_context->reply_cb = callback; - - if (service_clone(&request_clone, service) != SERVICE_ERROR_NONE) - { - free(request_context); - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the service request handle"); - } - - request_context->service = request_clone; - request_context->user_data = user_data; - } - - if (implicit_default_operation == true) - { - appsvc_set_operation(service->data, SERVICE_OPERATION_DEFAULT); - } - - launch_pid = appsvc_run_service(service->data, service->id, callback ? service_request_result_broker : NULL, request_context); - - if (implicit_default_operation == true) - { - bundle_del(service->data, BUNDLE_KEY_OPERATION); - } - - if (launch_pid < 0) - { - return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL); - } - - return SERVICE_ERROR_NONE; -} - -static bool service_copy_reply_data_cb(service_h service, const char *key, void *user_data) -{ - bundle *reply_data = user_data; - char *value = NULL; - char **value_array = NULL; - int value_array_length = 0; - int value_array_index = 0; - - if (reply_data == NULL) - { - service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - return false; - } - - if (appsvc_data_is_array(service->data, key)) - { - service_get_extra_data_array(service, key, &value_array, &value_array_length); - appsvc_add_data_array(reply_data, key, (const char**)value_array, value_array_length); - - for (value_array_index=0; value_array_index < value_array_length; value_array_index++) - { - free(value_array[value_array_index]); - } - - free(value_array); - } - else - { - service_get_extra_data(service, key, &value); - appsvc_add_data(reply_data, key, value); - free(value); - } - - return true; -} - -int service_reply_to_launch_request(service_h reply, service_h request, service_result_e result) -{ - bundle *reply_data; - int appsvc_result; - - if (service_valiate_service(reply) || service_valiate_service(request)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (appsvc_create_result_bundle(request->data, &reply_data) != 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle"); - } - - service_foreach_extra_data(reply, service_copy_reply_data_cb, reply_data); - - switch (result) - { - case SERVICE_RESULT_SUCCEEDED: - appsvc_result = APPSVC_RES_OK; - break; - - case SERVICE_RESULT_FAILED: - appsvc_result = APPSVC_RES_NOT_OK; - break; - - case SERVICE_RESULT_CANCELED: - appsvc_result = APPSVC_RES_CANCEL; - break; - - default: - appsvc_result = APPSVC_RES_CANCEL; - break; - } - - appsvc_send_result(reply_data, appsvc_result); - - return SERVICE_ERROR_NONE; -} - - -int service_add_extra_data(service_h service, const char *key, const char *value) -{ - if (service_valiate_service(service) || service_validate_extra_data(key) || service_validate_extra_data(value)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (service_validate_internal_key(key)) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); - } - - if (appsvc_get_data(service->data, key) != NULL) - { - // overwrite any existing value - bundle_del(service->data, key); - } - - if (appsvc_add_data(service->data, key, value) != 0) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle"); - } - - return SERVICE_ERROR_NONE; -} - - -int service_add_extra_data_array(service_h service, const char *key, const char* value[], int length) -{ - if (service_valiate_service(service) || service_validate_extra_data(key)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (value == NULL || length <= 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array"); - } - - if (service_validate_internal_key(key)) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); - } - - if (appsvc_get_data_array(service->data, key, NULL) != NULL) - { - // overwrite any existing value - bundle_del(service->data,key); - } - - if (appsvc_add_data_array(service->data, key, value, length) != 0) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle"); - } - - return SERVICE_ERROR_NONE; -} - - -int service_remove_extra_data(service_h service, const char *key) -{ - if (service_valiate_service(service) || service_validate_extra_data(key)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (service_validate_internal_key(key)) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); - } - - if (bundle_del(service->data, key)) - { - return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); - } - - return SERVICE_ERROR_NONE; -} - - -int service_get_extra_data(service_h service, const char *key, char **value) -{ - const char *data_value; - - if (service_valiate_service(service) || service_validate_extra_data(key) || value == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - - if (service_validate_internal_key(key)) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); - } - - data_value = appsvc_get_data(service->data, key); - - if (data_value == NULL) - { - if (errno == ENOTSUP) - { - return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); - } - else - { - return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); - } - } - - *value = strdup(data_value); - - return SERVICE_ERROR_NONE; -} - - -int service_get_extra_data_array(service_h service, const char *key, char ***value, int *length) -{ - const char **array_data; - int array_data_length; - char **array_data_clone; - int i; - - if (service_valiate_service(service) || service_validate_extra_data(key)) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (value == NULL || length == 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (service_validate_internal_key(key)) - { - return service_error(SERVICE_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use"); - } - - array_data = appsvc_get_data_array(service->data, key, &array_data_length); - - if (array_data == NULL) - { - if (errno == ENOTSUP) - { - return service_error(SERVICE_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL); - } - else - { - return service_error(SERVICE_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL); - } - } - - array_data_clone = calloc(array_data_length, sizeof(char*)); - - if (array_data_clone == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - } - - for (i=0; idata, key)) - { - *array = false; - } - else - { - *array = true; - } - - return SERVICE_ERROR_NONE; -} - - -typedef struct { - service_h service; - service_extra_data_cb callback; - void* user_data; - bool foreach_break; -} foreach_context_extra_data_t; - -static void service_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data) -{ - foreach_context_extra_data_t* foreach_context = NULL; - service_extra_data_cb extra_data_cb; - - if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY)) - { - return; - } - - foreach_context = (foreach_context_extra_data_t*)user_data; - - if (foreach_context->foreach_break == true) - { - return; - } - - if (service_validate_internal_key(key)) - { - return; - } - - extra_data_cb = foreach_context->callback; - - if (extra_data_cb != NULL) - { - bool stop_foreach = false; - - stop_foreach = !extra_data_cb(foreach_context->service, key, foreach_context->user_data); - - foreach_context->foreach_break = stop_foreach; - } - -} - - -int service_foreach_extra_data(service_h service, service_extra_data_cb callback, void *user_data) -{ - foreach_context_extra_data_t foreach_context = { - .service = service, - .callback = callback, - .user_data = user_data, - .foreach_break = false - }; - - if (service_valiate_service(service) || callback == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - bundle_foreach(service->data, service_cb_broker_bundle_iterator, &foreach_context); - - return SERVICE_ERROR_NONE; -} - -typedef struct { - service_h service; - service_app_matched_cb callback; - void* user_data; - bool foreach_break; -} foreach_context_launchable_app_t; - -int service_cb_broker_foreach_app_matched(const char *package, void *data) -{ - foreach_context_launchable_app_t *foreach_context; - service_app_matched_cb app_matched_cb; - - if (package == NULL || data == NULL) - { - service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - return -1; - } - - foreach_context = (foreach_context_launchable_app_t*)data; - - if (foreach_context->foreach_break == true) - { - return -1; - } - - app_matched_cb = foreach_context->callback; - - if (app_matched_cb != NULL) - { - bool stop_foreach = false; - - stop_foreach = !app_matched_cb(foreach_context->service, package, foreach_context->user_data); - - foreach_context->foreach_break = stop_foreach; - } - - return 0; -} - -int service_foreach_app_matched(service_h service, service_app_matched_cb callback, void *user_data) -{ - foreach_context_launchable_app_t foreach_context = { - .service = service, - .callback = callback, - .user_data = user_data, - .foreach_break = false - }; - - if (service_valiate_service(service) || callback == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - appsvc_get_list(service->data, service_cb_broker_foreach_app_matched, &foreach_context); - - return SERVICE_ERROR_NONE; -} - - -int service_get_caller(service_h service, char **package) -{ - const char *bundle_value; - pid_t caller_pid; - char package_buf[TIZEN_PATH_MAX] = {0, }; - char *package_dup; - - if (service_valiate_service(service) || package == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (service->type != SERVICE_TYPE_EVENT) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type"); - } - - bundle_value = bundle_get_val(service->data, AUL_K_ORG_CALLER_PID); - - if (bundle_value == NULL) - { - bundle_value = bundle_get_val(service->data, AUL_K_CALLER_PID); - } - - if (bundle_value == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the pid of the caller"); - } - - caller_pid = atoi(bundle_value); - - if (caller_pid <= 0) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid pid of the caller"); - } - - if (aul_app_get_pkgname_bypid(caller_pid, package_buf, sizeof(package_buf)) != AUL_R_OK) - { - return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, "failed to get the package name of the caller"); - } - - package_dup = strdup(package_buf); - - if (package_dup == NULL) - { - return service_error(SERVICE_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - } - - *package = package_dup; - - return SERVICE_ERROR_NONE; -} - - -int service_is_reply_requested(service_h service, bool *requested) -{ - const char *bundle_value; - - if (service_valiate_service(service) || requested == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - if (service->type != SERVICE_TYPE_EVENT) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid service handle type"); - } - - bundle_value = bundle_get_val(service->data, AUL_K_WAIT_RESULT); - - if (bundle_value != NULL) - { - *requested = true; - } - else - { - *requested = false; - } - - return SERVICE_ERROR_NONE; -} - -int service_import_from_bundle(service_h service, bundle *data) -{ - bundle *data_dup = NULL; - - if (service_valiate_service(service) || data == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - data_dup = bundle_dup(data); - - if (data_dup == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); - } - - if (service->data != NULL) - { - bundle_free(service->data); - } - - service->data = data_dup; - - return SERVICE_ERROR_NONE; -} - -int service_export_as_bundle(service_h service, bundle **data) -{ - bundle *data_dup = NULL; - - if (service_valiate_service(service) || data == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } - - data_dup = bundle_dup(service->data); - - if (data_dup == NULL) - { - return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle"); - } - - *data = data_dup; - - return SERVICE_ERROR_NONE; -} - diff --git a/src/storage.c b/src/storage.c deleted file mode 100755 index e5b4a44..0000000 --- a/src/storage.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_STORAGE" - -static int storage_initialize(); -static int storage_register_device(storage_device_h device); -static int storage_get_storage(int id, storage_info_h* storage_info); - -extern storage_device_h storage_internal_device(); -extern storage_device_h storage_sdcard_device(); -extern storage_device_h storage_usbhost_device(); - - -#define STORAGE_MAX 3 -static struct storage_info_s storage_info_table[STORAGE_MAX]; -static int storage_num = 0; - -static int storage_register_device(storage_device_h device) -{ - if (device == NULL) - { - return -1; - } - - if (storage_num >= STORAGE_MAX) - { - LOGE("[%s] failed to register device : not enough device table", __FUNCTION__); - return -1; - } - - storage_info_table[storage_num].id = storage_num; - storage_info_table[storage_num].device = device; - storage_info_table[storage_num].state = device->get_state(); - storage_info_table[storage_num].state_cb = NULL; - storage_info_table[storage_num].state_cb_data = NULL; - - storage_num++; - - return 0; -} - -static int storage_initialize() -{ - storage_device_h dev_internal; - storage_device_h dev_sdcard; - storage_device_h dev_usbhost; - - dev_internal = storage_internal_device(); - storage_register_device(dev_internal); - - dev_sdcard = storage_sdcard_device(); - storage_register_device( dev_sdcard); - - dev_usbhost = storage_usbhost_device(); - storage_register_device(dev_usbhost); - - return 0; -} - - -static int storage_get_storage(int id, storage_info_h* storage_info) -{ - if (storage_num < 1) - { - if (storage_initialize() != 0) - { - return STORAGE_ERROR_NOT_SUPPORTED; - } - } - - if (id <0 || id >= storage_num) - { - return STORAGE_ERROR_NOT_SUPPORTED; - } - - *storage_info = &(storage_info_table[id]); - - return STORAGE_ERROR_NONE; -} - - -int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data) -{ - int storage_id = 0; - storage_info_h storage_info = NULL; - bool foreach_next = false; - - if (callback == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid callback", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - while (true) - { - if (storage_get_storage(storage_id, &storage_info) != 0) - { - break; - } - - storage_id++; - - foreach_next = callback(storage_info->id, storage_info->device->type, storage_info->state, storage_info->device->path, user_data); - - if (foreach_next == false) - { - break; - } - } - - return STORAGE_ERROR_NONE; -} - - -int storage_get_root_directory(int storage, char **path) -{ - storage_info_h storage_info; - - if (path == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - *path = strdup(storage_info->device->path); - - return STORAGE_ERROR_NONE; -} - - -int storage_get_type(int storage, storage_type_e *type) -{ - storage_info_h storage_info; - - if (type == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - *type = storage_info->device->type; - - return STORAGE_ERROR_NONE; -} - - -int storage_get_state(int storage, storage_state_e *state) -{ - storage_info_h storage_info; - storage_dev_get_state get_state; - - if (state == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - get_state = storage_info->device->get_state; - - if (get_state == NULL) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - storage_info->state = get_state(); - - *state = storage_info->state; - - return STORAGE_ERROR_NONE; -} - - -void storage_dispatch_state_event(storage_state_e state, void* data) -{ - storage_info_h storage_info; - storage_state_changed_cb state_cb; - - storage_info = data; - - if (storage_info == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid storage information", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return; - } - - storage_info->state = state; - state_cb = storage_info->state_cb; - - if (state_cb != NULL) - { - state_cb(storage_info->id, state, storage_info->state_cb_data); - } -} - - -int storage_set_state_changed_cb(int storage, storage_state_changed_cb callback, void *user_data) -{ - storage_info_h storage_info; - storage_dev_set_state_cb set_state_cb; - - if (callback == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid callback", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - storage_info->state_cb = callback; - storage_info->state_cb_data = user_data; - - set_state_cb = storage_info->device->set_state_cb; - - if (set_state_cb == NULL) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - if (set_state_cb(storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - return STORAGE_ERROR_NONE; -} - - -int storage_unset_state_changed_cb(int storage) -{ - storage_info_h storage_info; - storage_dev_unset_state_cb unset_state_cb; - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - storage_info->state_cb = NULL; - unset_state_cb = storage_info->device->unset_state_cb; - - if (unset_state_cb != NULL) - { - unset_state_cb(); - } - - return STORAGE_ERROR_NONE; -} - - -int storage_get_total_space(int storage, unsigned long long *bytes) -{ - storage_info_h storage_info; - storage_dev_get_space get_space; - - if (bytes == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - get_space = storage_info->device->get_space; - - if (get_space == NULL) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - if (get_space(bytes, NULL) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - return STORAGE_ERROR_NONE; -} - -int storage_get_available_space(int storage, unsigned long long *bytes) -{ - storage_info_h storage_info; - storage_dev_get_space get_space; - - if (bytes == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, STORAGE_ERROR_INVALID_PARAMETER); - return STORAGE_ERROR_INVALID_PARAMETER; - } - - if (storage_get_storage(storage, &storage_info) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - get_space = storage_info->device->get_space; - - if (get_space == NULL) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - if (get_space(NULL, bytes) != 0) - { - LOGE("[%s] NOT_SUPPORTED(0x%08x) : storage(%d)", __FUNCTION__, STORAGE_ERROR_NOT_SUPPORTED, storage); - return STORAGE_ERROR_NOT_SUPPORTED; - } - - return STORAGE_ERROR_NONE; -} - -int storage_statfs(const char *directory, unsigned long long *total, unsigned long long *available) -{ - struct statfs fs; - - if (statfs(directory, &fs) < 0) - { - LOGE("[%s] statfs returns error(%d) directory(%s)\n", __FUNCTION__, errno, directory); - return -1; - } - - if (total != NULL) - { - *total = fs.f_bsize * fs.f_blocks; - } - - if (available != NULL) - { - *available = fs.f_bsize * fs.f_bavail; - } - - return 0; -} - diff --git a/src/storage_internal.c b/src/storage_internal.c deleted file mode 100755 index 003ed4d..0000000 --- a/src/storage_internal.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_STORAGE" - -#define INTERNAL_MEMORY_PATH "/opt/media" - -static int storage_internal_get_state() -{ - return STORAGE_STATE_MOUNTED; -} - -static int storage_internal_set_state_cb(void *data) -{ - return 0; -} - -static void storage_internal_unset_state_cb() -{ - // empty function -} - -int storage_internal_get_space(unsigned long long *total, unsigned long long *available) -{ - return storage_statfs(INTERNAL_MEMORY_PATH, total, available); -} - -storage_device_h storage_internal_device() -{ - storage_device_h device; - - device = calloc(1, sizeof(struct storage_device_s)); - - if (device == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, STORAGE_ERROR_OUT_OF_MEMORY); - return NULL; - } - - device->type = STORAGE_TYPE_INTERNAL; - device->path = INTERNAL_MEMORY_PATH; - device->get_state = storage_internal_get_state; - device->set_state_cb = storage_internal_set_state_cb; - device->unset_state_cb = storage_internal_unset_state_cb; - device->get_space = storage_internal_get_space; - - return device; -} - diff --git a/src/storage_sdcard.c b/src/storage_sdcard.c deleted file mode 100755 index c984ee5..0000000 --- a/src/storage_sdcard.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_STORAGE" - -#define SDCARD_PATH "/opt/storage/sdcard" - -static int storage_sdcard_get_state() -{ - int sdcard_state = 0; - - vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &sdcard_state); - - switch (sdcard_state) - { - case VCONFKEY_SYSMAN_MMC_REMOVED: - return STORAGE_STATE_REMOVED; - - case VCONFKEY_SYSMAN_MMC_MOUNTED: - return STORAGE_STATE_MOUNTED; - - case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED: - return STORAGE_STATE_UNMOUNTABLE; - - default: - return STORAGE_STATE_REMOVED; - } -} - -static void storage_sdcard_state_cb_broker(keynode_t* key, void* data) -{ - storage_state_e state; - state = storage_sdcard_get_state(); - - storage_dispatch_state_event(state, data); -} - -static int storage_sdcard_set_state_cb(void *data) -{ - vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, storage_sdcard_state_cb_broker, data); - return 0; -} - -static void storage_sdcard_unset_state_cb() -{ - vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, storage_sdcard_state_cb_broker); -} - -static int storage_sdcard_get_space(unsigned long long *total, unsigned long long *available) -{ - storage_state_e state; - state = storage_sdcard_get_state(); - - if (state < STORAGE_STATE_MOUNTED) - { - if (total != NULL) - { - *total = 0; - } - - if (available != NULL) - { - *available = 0; - } - - return 0; - } - else - { - return storage_statfs(SDCARD_PATH, total, available); - } -} - -storage_device_h storage_sdcard_device() -{ - storage_device_h device; - - device = calloc(1, sizeof(struct storage_device_s)); - - if (device == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, STORAGE_ERROR_OUT_OF_MEMORY); - return NULL; - } - - device->type = STORAGE_TYPE_EXTERNAL; - device->path = SDCARD_PATH; - device->get_state = storage_sdcard_get_state; - device->set_state_cb = storage_sdcard_set_state_cb; - device->unset_state_cb = storage_sdcard_unset_state_cb; - device->get_space = storage_sdcard_get_space; - - return device; -} - diff --git a/src/storage_usbhost.c b/src/storage_usbhost.c deleted file mode 100755 index b686440..0000000 --- a/src/storage_usbhost.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_STORAGE" - -#define USBHOST_PATH "/opt/storage/usb" - -static int storage_usbhost_get_state() -{ - int usbhost_state = 0; - - vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &usbhost_state); - - switch (usbhost_state) - { - case VCONFKEY_SYSMEN_USB_HOST_DISCONNECTED: - return STORAGE_STATE_REMOVED; - - case VCONFKEY_SYSMEN_USB_HOST_CONNECTED: - return STORAGE_STATE_MOUNTED; - - default: - return STORAGE_STATE_REMOVED; - } -} - -static void storage_usbhost_state_cb_broker(keynode_t* key, void* data) -{ - storage_state_e state; - - state = storage_usbhost_get_state(); - - storage_dispatch_state_event(state, data); -} - -static int storage_usbhost_set_state_cb(void *data) -{ - vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_HOST_STATUS, storage_usbhost_state_cb_broker, data); - return 0; -} - -static void storage_usbhost_unset_state_cb() -{ - vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_HOST_STATUS, storage_usbhost_state_cb_broker); -} - - -static int storage_usbhost_get_space(unsigned long long *total, unsigned long long *available) -{ - storage_state_e state; - state = storage_usbhost_get_state(); - - if (state < STORAGE_STATE_MOUNTED) - { - if (total != NULL) - { - *total = 0; - } - - if (available != NULL) - { - *available = 0; - } - - return 0; - } - else - { - return storage_statfs(USBHOST_PATH, total, available); - } -} - - -storage_device_h storage_usbhost_device() -{ - storage_device_h device; - - device = calloc(1, sizeof(struct storage_device_s)); - - if (device == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, STORAGE_ERROR_OUT_OF_MEMORY); - return NULL; - } - - device->type = STORAGE_TYPE_EXTERNAL; - device->path = USBHOST_PATH; - device->get_state = storage_usbhost_get_state; - device->set_state_cb = storage_usbhost_set_state_cb; - device->unset_state_cb = storage_usbhost_unset_state_cb; - device->get_space = storage_usbhost_get_space; - - return device; -} - diff --git a/src/ui_notification.c b/src/ui_notification.c deleted file mode 100755 index 16d6b25..0000000 --- a/src/ui_notification.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "TIZEN_N_UI_NOTIFICATION" - -struct ui_notification_s { - notification_h raw_handle; - bool ongoing; - bool posted; - bool removed; - char *icon; - struct tm *time; - char *title; - char *content; - service_h service; - char *sound; - bool vibration; -}; - -static int ui_notification_error_handler(int error, const char *func, const char *on_error) -{ - int retcode; - char *error_msg; - - switch (error) - { - case NOTIFICATION_ERROR_NONE: - retcode = UI_NOTIFICATION_ERROR_NONE; - break; - - case NOTIFICATION_ERROR_INVALID_DATA: - retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - error_msg = "INVALID_PARAMETER"; - break; - - case NOTIFICATION_ERROR_NO_MEMORY: - retcode = UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - error_msg = "OUT_OF_MEMORY"; - break; - - case NOTIFICATION_ERROR_FROM_DB: - retcode = UI_NOTIFICATION_ERROR_DB_FAILED; - error_msg = "DB_FAILED"; - break; - - case NOTIFICATION_ERROR_ALREADY_EXIST_ID: - case NOTIFICATION_ERROR_NOT_EXIST_ID: - retcode = UI_NOTIFICATION_ERROR_INVALID_STATE; - error_msg = "INVALID_STATE"; - break; - - default: - retcode = UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - error_msg = "INVALID_PARAMETER"; - } - - if (retcode != UI_NOTIFICATION_ERROR_NONE) - { - LOGE("[%s] %s(0x%08x) : %s", func, error_msg, retcode, on_error); - } - - return retcode; -} - - -int ui_notification_create(bool ongoing, ui_notification_h *notification) -{ - ui_notification_h notification_out; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s)); - - if (notification_out == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - notification_out->raw_handle = NULL; - notification_out->ongoing = ongoing; - notification_out->posted = false; - notification_out->removed = false; - notification_out->icon = NULL; - notification_out->time = NULL; - notification_out->title = NULL; - notification_out->content = NULL; - notification_out->service = NULL; - notification_out->sound = NULL; - notification_out->vibration = false; - - *notification = notification_out; - - return UI_NOTIFICATION_ERROR_NONE; -} - -static int ui_notification_construct(bool ongoing, notification_h raw_handle, ui_notification_h *notification) -{ - int retcode; - ui_notification_h notification_out; - char *icon; - time_t time; - char *title; - char *content; - bundle *service_data; - const char *sound = NULL; - notification_sound_type_e sound_type; - notification_vibration_type_e vib_type; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid output param", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s)); - - if (notification_out == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - retcode = ui_notification_error_handler(notification_clone(raw_handle, &(notification_out->raw_handle)),\ - __FUNCTION__, "failed to clone the notification handle"); - - if (retcode != NOTIFICATION_ERROR_NONE) - { - return retcode; - } - - notification_out->ongoing = ongoing; - - notification_out->posted = true; - - notification_out->removed = false; - - if (!notification_get_image(raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, &icon) && icon) - { - notification_out->icon = strdup(icon); - } - - if (!notification_get_time(raw_handle, &time)) - { - notification_out->time = malloc(sizeof(struct tm)); - - if (notification_out->time == NULL) - { - ui_notification_destroy(notification_out); - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - localtime_r(&time, notification_out->time); - } - - if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, &title) && title) - { - notification_out->title = strdup(title); - } - - if (!notification_get_text(raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, &content) && content) - { - notification_out->content = strdup(content); - } - - if (!notification_get_sound(raw_handle, &sound_type, &sound) && sound) - { - notification_out->sound = strdup(sound); - } - - if (!notification_get_vibration(raw_handle, &vib_type, NULL)) - { - if (vib_type == NOTIFICATION_VIBRATION_TYPE_DEFAULT) - { - notification_out->vibration = true; - } - } - - if (!notification_get_execute_option(raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, &service_data)) - { - service_h service; - - if (!service_create_request(service_data, &service)) - { - notification_out->service = service; - } - } - - *notification = notification_out; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_destroy(ui_notification_h notification) -{ - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->raw_handle) - notification_free(notification->raw_handle); - - if (notification->icon) - free(notification->icon); - - if (notification->time) - free(notification->time); - - if (notification->title) - free(notification->title); - - if (notification->content) - free(notification->content); - - if (notification->sound) - free(notification->sound); - - if (notification->service) - service_destroy(notification->service); - - free(notification); - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_clone(ui_notification_h *clone, ui_notification_h notification) -{ - ui_notification_h notification_out; - int retcode; - - if (clone == NULL || notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - notification_out = (ui_notification_h)calloc(1, sizeof(struct ui_notification_s)); - - if (notification->raw_handle != NULL) - { - retcode = notification_clone(notification->raw_handle, &(notification_out->raw_handle)); - - if (retcode) - { - return ui_notification_error_handler(retcode, __FUNCTION__, "failed to clone the handle"); - } - } - - notification_out->ongoing = notification->ongoing; - - notification_out->posted = notification->posted; - - notification_out->removed = notification->removed; - - if (notification->icon) - { - notification_out->icon = strdup(notification->icon); - } - - if (notification->time) - { - notification_out->time = malloc(sizeof(struct tm)); - if (notification_out->time != NULL) - { - memcpy(notification_out->time, notification->time, sizeof(struct tm)); - } - } - - if (notification->title) - { - notification_out->title = strdup(notification->title); - } - - if (notification->content) - { - notification_out->content = strdup(notification->content); - } - - if (notification->sound) - { - notification_out->sound = strdup(notification->sound); - } - - notification_out->vibration = notification->vibration; - - if (notification->service) - { - service_clone(&(notification_out->service), notification->service); - } - - *clone = notification_out; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_is_ongoing(ui_notification_h notification, bool *ongoing) -{ - if (notification == NULL || ongoing == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - *ongoing = notification->ongoing; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_set_icon(ui_notification_h notification, const char *path) -{ - char *path_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (path != NULL) - { - path_dup = strdup(path); - - if (path_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - if (notification->icon != NULL) - { - free(notification->icon); - } - - notification->icon = path_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_icon(ui_notification_h notification, char **path) -{ - char *path_dup = NULL; - - if (notification == NULL || path == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->icon != NULL) - { - path_dup = strdup(notification->icon); - - if (path_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - *path = path_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_set_time(ui_notification_h notification, struct tm *time) -{ - struct tm *time_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (time != NULL) - { - time_dup = malloc(sizeof(struct tm)); - - if (time_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - memcpy(time_dup, time, sizeof(struct tm)); - } - - if (notification->time != NULL) - { - free(notification->time); - } - - notification->time = time_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_time(ui_notification_h notification, struct tm **time) -{ - struct tm *time_dup = NULL; - - if (notification == NULL || time == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->time != NULL) - { - time_dup = malloc(sizeof(struct tm)); - - if (time_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - memcpy(time_dup, notification->time, sizeof(struct tm)); - } - - *time = time_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_set_title(ui_notification_h notification, const char *title) -{ - char *title_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (title != NULL) - { - title_dup = strdup(title); - - if (title_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - if (notification->title != NULL) - { - free(notification->title); - } - - notification->title = title_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_title(ui_notification_h notification, char **title) -{ - char *title_dup = NULL; - - if (notification == NULL || title == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->title != NULL) - { - title_dup = strdup(notification->title); - - if (title_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - *title = title_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - - -int ui_notification_set_content(ui_notification_h notification, const char *content) -{ - char *content_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (content != NULL) - { - content_dup = strdup(content); - - if (content_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - if (notification->content != NULL) - { - free(notification->content); - } - - notification->content = content_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_content(ui_notification_h notification, char **content) -{ - char *content_dup = NULL; - - if (notification == NULL || content == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->content != NULL) - { - content_dup = strdup(notification->content); - - if (content_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - *content = content_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - - -int ui_notification_set_service(ui_notification_h notification, service_h service) -{ - int retcode; - service_h service_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (service != NULL) - { - retcode = service_clone(&service_dup, service); - - if (retcode != SERVICE_ERROR_NONE) - { - if (retcode == SERVICE_ERROR_OUT_OF_MEMORY) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - else - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - } - } - - if (notification->service != NULL) - { - service_destroy(notification->service); - } - - notification->service = service_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_service(ui_notification_h notification, service_h *service) -{ - int retcode; - service_h service_dup = NULL; - - if (notification == NULL || service == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->service != NULL) - { - retcode = service_clone(&service_dup, notification->service); - - if (retcode != SERVICE_ERROR_NONE) - { - if (retcode == SERVICE_ERROR_OUT_OF_MEMORY) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - else - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid service handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - } - } - - *service = service_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_set_sound(ui_notification_h notification, const char *path) -{ - char *path_dup = NULL; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (path != NULL) - { - path_dup = strdup(path); - - if (path_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - if (notification->sound != NULL) - { - free(notification->sound); - } - - notification->sound = path_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_sound(ui_notification_h notification, char **path) -{ - char *path_dup = NULL; - - if (notification == NULL || path == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->sound != NULL) - { - path_dup = strdup(notification->sound); - - if (path_dup == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - *path = NULL; - - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - } - - *path = path_dup; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_set_vibration(ui_notification_h notification, bool value) -{ - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - notification->vibration = value; - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_get_vibration(ui_notification_h notification, bool *value) -{ - if (notification == NULL || value == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - *value = notification->vibration; - - return UI_NOTIFICATION_ERROR_NONE; -} - -static int ui_notification_build_attributes(ui_notification_h notification) -{ - bundle *service_data; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->icon != NULL) - { - struct stat st; - - if (stat(notification->icon, &st) < 0) - { - LOGE("[%s] NO_SUCH_FILE(0x%08x) : invalid icon", __FUNCTION__, UI_NOTIFICATION_ERROR_NO_SUCH_FILE); - return UI_NOTIFICATION_ERROR_NO_SUCH_FILE; - } - - notification_set_image(notification->raw_handle, NOTIFICATION_IMAGE_TYPE_ICON, notification->icon); - } - - if (notification->time != NULL) - { - notification_set_time(notification->raw_handle, mktime(notification->time)); - } - - if (notification->title != NULL) - { - notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_TITLE, notification->title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE); - } - - if (notification->content != NULL) - { - notification_set_text(notification->raw_handle, NOTIFICATION_TEXT_TYPE_CONTENT, notification->content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE); - } - - if (notification->service != NULL && service_to_bundle(notification->service, &service_data) == SERVICE_ERROR_NONE) - { - notification_set_property(notification->raw_handle, 0); - notification_set_execute_option(notification->raw_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, NULL, NULL, service_data); - } - else - { - notification_set_property(notification->raw_handle, NOTIFICATION_PROP_DISABLE_APP_LAUNCH); - } - - if (notification->sound != NULL) - { - struct stat st; - - if (stat(notification->sound, &st) < 0) - { - LOGE("[%s] NO_SUCH_FILE(0x%08x) : invalid sound file", __FUNCTION__, UI_NOTIFICATION_ERROR_NO_SUCH_FILE); - return UI_NOTIFICATION_ERROR_NO_SUCH_FILE; - } - notification_set_sound(notification->raw_handle, NOTIFICATION_SOUND_TYPE_USER_DATA, notification->sound); - } - - if (notification->vibration) - { - notification_set_vibration(notification->raw_handle, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL); - } - - return UI_NOTIFICATION_ERROR_NONE; -} - -int ui_notification_post(ui_notification_h notification) -{ - int retcode; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->posted == true) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was already posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - if (notification->ongoing == true) - { - notification->raw_handle = notification_new(NOTIFICATION_TYPE_ONGOING, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE); - } - else - { - notification->raw_handle = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_DEFAULT, NOTIFICATION_PRIV_ID_NONE); - } - - if (notification->raw_handle == NULL) - { - LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_OUT_OF_MEMORY); - return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY; - } - - retcode = ui_notification_build_attributes(notification); - - if (retcode != UI_NOTIFICATION_ERROR_NONE) - { - return retcode; - } - - retcode = ui_notification_error_handler(notification_insert(notification->raw_handle, NULL), __FUNCTION__, "failed to post a notification"); - - if (retcode == UI_NOTIFICATION_ERROR_NONE) - { - notification->posted = true; - } - - return retcode; -} - -int ui_notification_update(ui_notification_h notification) -{ - int retcode; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->posted == false) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - if (notification->removed == true) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - retcode = ui_notification_build_attributes(notification); - - if (retcode != UI_NOTIFICATION_ERROR_NONE) - { - return retcode; - } - - retcode = ui_notification_error_handler(notification_update(notification->raw_handle), __FUNCTION__, "failed to post a notification"); - - if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE) - { - notification->removed = true; - } - - return retcode; -} - -int ui_notification_update_progress(ui_notification_h notification, ui_notification_progress_type_e type, double value) -{ - int retcode; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->raw_handle == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->posted == false) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - if (notification->removed == true) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - if (value < 0) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : the value must be greater than or equal to zero.", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - switch (type) - { - case UI_NOTIFICATION_PROGRESS_TYPE_SIZE: - retcode = ui_notification_error_handler( - notification_update_size(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value), - __FUNCTION__, "failed to update the progress"); - break; - - case UI_NOTIFICATION_PROGRESS_TYPE_PERCENTAGE: - retcode = ui_notification_error_handler( - notification_update_progress(notification->raw_handle, NOTIFICATION_PRIV_ID_NONE, value), - __FUNCTION__, "failed to update the progress"); - break; - - default: - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid progress type", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (retcode == UI_NOTIFICATION_ERROR_INVALID_STATE) - { - notification->removed = true; - } - - return retcode; -} - -int ui_notification_cancel(ui_notification_h notification) -{ - int retcode; - - if (notification == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->raw_handle == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid handle", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification->posted == false) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was not posted", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - if (notification->removed == true) - { - LOGE("[%s] INVALID_STATE(0x%08x) : the notification was canceled or cleared", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_STATE); - return UI_NOTIFICATION_ERROR_INVALID_STATE; - } - - retcode = ui_notification_error_handler(notification_delete(notification->raw_handle), __FUNCTION__, "failed to cancel the notification"); - - if (retcode == UI_NOTIFICATION_ERROR_NONE) - { - notification->removed = true; - } - - return retcode; -} - -void ui_notification_cancel_all(void) -{ - notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NONE); -} - -void ui_notification_cancel_all_by_type(bool ongoing) -{ - notification_type_e type = NOTIFICATION_TYPE_NONE; - - if (ongoing) - type = NOTIFICATION_TYPE_ONGOING; - else - type = NOTIFICATION_TYPE_NOTI; - - notification_delete_all_by_type(NULL, type); -} - -void ui_notification_cancel_all_by_package(const char *package, bool ongoing) -{ - notification_type_e type = NOTIFICATION_TYPE_NONE; - - if (ongoing) - type = NOTIFICATION_TYPE_ONGOING; - else - type = NOTIFICATION_TYPE_NOTI; - - notification_delete_all_by_type(package, type); -} - -int ui_notification_cancel_all_by_app_id(const char *app_id, bool ongoing) -{ - notification_type_e type = NOTIFICATION_TYPE_NONE; - - if (app_id == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (ongoing) - type = NOTIFICATION_TYPE_ONGOING; - else - type = NOTIFICATION_TYPE_NOTI; - - notification_delete_all_by_type(app_id, type); - - return UI_NOTIFICATION_ERROR_NONE; -} - -static bool ui_notification_package_equal(notification_h handle) -{ - char *package = NULL; - char *handle_package = NULL; - - if (app_get_package(&package)) - { - return false; - } - - if (notification_get_pkgname(handle, &handle_package)) - { - return false; - } - - if (strlen(package) == strlen(handle_package)) - { - if (!strncmp(package, handle_package, strlen(package))) - { - return true; - } - } - - return false; -} - -int ui_notification_foreach_notification_posted(bool ongoing, ui_notification_cb callback, void *user_data) -{ - notification_list_h raw_handle_list; - notification_h raw_handle; - notification_type_e notification_type = ongoing ? NOTIFICATION_TYPE_ONGOING : NOTIFICATION_TYPE_NOTI; - ui_notification_h notification = NULL; - bool iterate_next = true; - - if (callback == NULL) - { - LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, UI_NOTIFICATION_ERROR_INVALID_PARAMETER); - return UI_NOTIFICATION_ERROR_INVALID_PARAMETER; - } - - if (notification_get_grouping_list(notification_type, -1, &raw_handle_list)) - { - LOGE("[%s] DB_FAILED(0x%08x) : failed to get a notification list", __FUNCTION__, UI_NOTIFICATION_ERROR_DB_FAILED); - return UI_NOTIFICATION_ERROR_DB_FAILED; - } - - while (raw_handle_list != NULL) - { - raw_handle = notification_list_get_data(raw_handle_list); - - if (raw_handle != NULL && ui_notification_package_equal(raw_handle)) - { - if (!ui_notification_construct(ongoing, raw_handle, ¬ification)) - { - iterate_next = callback(notification, user_data); - - ui_notification_destroy(notification); - - if (iterate_next == false) - { - break; - } - } - } - - raw_handle_list = notification_list_get_next(raw_handle_list); - } - - notification_free_list(raw_handle_list); - - return UI_NOTIFICATION_ERROR_NONE; -} - -- 2.7.4