summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:45:44 +0900
committerJinkun Jang <jinkun.jang@samsung.com>2013-03-13 01:45:44 +0900
commite3038c9c3c7a5c7843d872f2899ffa10abc03cb4 (patch)
treefd2d8b09ca59f58e8737588c77315595ce65e7eb /src
parent5611ff5660d14d0ea707447e84ee4c0626b71104 (diff)
downloadapplication-e3038c9c3c7a5c7843d872f2899ffa10abc03cb4.tar.gz
application-e3038c9c3c7a5c7843d872f2899ffa10abc03cb4.tar.bz2
application-e3038c9c3c7a5c7843d872f2899ffa10abc03cb4.zip
Tizen 2.1 base
Diffstat (limited to 'src')
-rwxr-xr-xsrc/alarm.c586
-rwxr-xr-xsrc/app_device.c83
-rwxr-xr-xsrc/app_error.c72
-rwxr-xr-xsrc/app_finalizer.c108
-rwxr-xr-xsrc/app_main.c401
-rwxr-xr-xsrc/app_package.c188
-rwxr-xr-xsrc/app_resource.c250
-rwxr-xr-xsrc/i18n.c29
-rwxr-xr-xsrc/preference.c758
-rwxr-xr-xsrc/service.c1285
-rwxr-xr-xsrc/storage.c397
-rwxr-xr-xsrc/storage_internal.c79
-rwxr-xr-xsrc/storage_sdcard.c125
-rwxr-xr-xsrc/storage_usbhost.c125
-rwxr-xr-xsrc/ui_notification.c1179
15 files changed, 5665 insertions, 0 deletions
diff --git a/src/alarm.c b/src/alarm.c
new file mode 100755
index 0000000..5b787af
--- /dev/null
+++ b/src/alarm.c
@@ -0,0 +1,586 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <aul.h>
+#include <alarm.h>
+#include <dlog.h>
+
+#include <app_private.h>
+#include <app_alarm.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_ALARM"
+
+typedef struct {
+ alarm_registered_alarm_cb cb;
+ void* user_data;
+ bool* foreach_break;
+} alarm_foreach_item_cb_context;
+
+static void alarm_get_interval(alarm_entry_t *alarm_info, int day_week, int *repeat_interval)
+{
+ time_t due_time = 0;
+ time_t current_time = 0;
+ struct tm duetime_tm;
+ int wday;
+ int interval = 0;
+
+ time(&current_time);
+ localtime_r(&current_time, &duetime_tm);
+ wday = duetime_tm.tm_wday;
+
+ due_time = mktime(&duetime_tm);
+ wday = duetime_tm.tm_wday;
+
+ if (due_time > current_time && day_week == 0)
+ return;
+
+ if (!(day_week & 1 << wday)) {
+ int day = wday + 1;
+ int next_week = 0;
+ interval = 1;
+ /*this week */
+
+ if (day == 7) {
+ day = 0;
+ next_week = 1;
+ }
+
+ while (!(day_week & 1 << day)
+ && interval < 8) {
+ day += 1;
+ interval += 1;
+
+ if (day == 7) {
+ day = 0;
+ next_week = 1;
+ }
+
+ }
+ *repeat_interval = interval;
+ }
+}
+
+static int alarm_registered_alarm_cb_broker(int alarm_id, void *user_data)
+{
+ alarm_foreach_item_cb_context* foreach_cb_context = NULL;
+
+ if (user_data == NULL)
+ {
+ return 0;
+ }
+
+ foreach_cb_context = (alarm_foreach_item_cb_context*)user_data;
+
+ if (foreach_cb_context != NULL && *(foreach_cb_context->foreach_break) == false)
+ {
+ if (foreach_cb_context->cb(alarm_id, foreach_cb_context->user_data) == false)
+ {
+ *(foreach_cb_context->foreach_break) = true;
+ }
+ }
+
+ return 0;
+}
+
+static int convert_error_code_to_alarm(const char* function, alarm_error_t alarm_error)
+{
+ switch(alarm_error)
+ {
+ case ERR_ALARM_INVALID_PARAM:
+ case ERR_ALARM_INVALID_REPEAT:
+ LOGE("[%s] INVALID_PARAMETER(0x%08x)", function, ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ break;
+
+ case ERR_ALARM_INVALID_ID:
+ LOGE("[%s] INVALID_PARAMETER(0x%08x)", function, ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ break;
+
+ case ERR_ALARM_INVALID_TIME:
+ LOGE("[%s] INVALID_TIME(0x%08x)", function, ALARM_ERROR_INVALID_TIME);
+ return ALARM_ERROR_INVALID_TIME;
+ break;
+
+ case ERR_ALARM_INVALID_DATE:
+ 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;
+ break;
+
+ case ERR_ALARM_SYSTEM_FAIL:
+ LOGE("[%s] CONNECTION_FAIL(0x%08x)", function, ALARM_ERROR_CONNECTION_FAIL);
+ return ALARM_ERROR_CONNECTION_FAIL;
+ break;
+
+ case ALARMMGR_RESULT_SUCCESS:
+ return ALARM_ERROR_NONE;
+ break;
+
+ default:
+ 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;
+ alarm_repeat_mode_t repeat=0;
+ int week_day=0;
+ int repeat_interval=0;
+
+ if (date == NULL)
+ {
+ 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);
+ }
+
+ result = alarmmgr_get_repeat_mode(entry, &repeat, &week_day);
+
+ if (result != ALARMMGR_RESULT_SUCCESS)
+ {
+ if (entry != NULL)
+ {
+ alarmmgr_free_alarm(entry);
+ }
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+ }
+
+ if ( repeat == ALARM_REPEAT_MODE_WEEKLY)
+ alarm_get_interval(entry, week_day, &repeat_interval);
+ else
+ repeat_interval=0;
+
+ alarm_get_current_time(date);
+
+ date->tm_year = adate.year - 1900;
+ date->tm_mon = adate.month - 1;
+ date->tm_mday = adate.day + repeat_interval;
+ date->tm_hour = adate.hour;
+ date->tm_min = adate.min;
+ date->tm_sec = adate.sec;
+
+ mktime(date);
+
+ result = alarmmgr_free_alarm(entry);
+ if (result != ALARMMGR_RESULT_SUCCESS)
+ {
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+ }
+
+ return ALARM_ERROR_NONE;
+
+}
+
+int alarm_get_scheduled_period(int alarm_id, int* period)
+{
+ alarm_error_t result;
+ alarm_entry_t *entry = NULL;
+ alarm_repeat_mode_t mode;
+ int value;
+
+ if (period == NULL)
+ {
+ 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_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);
+ }
+
+ result = alarmmgr_free_alarm(entry);
+ if(result != ALARMMGR_RESULT_SUCCESS)
+ {
+ 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)
+{
+ bundle *bundle_data;
+ int result = 0;
+
+ if (service == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE)
+ {
+ 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)
+{
+ alarm_date_t internal_time;
+ alarm_entry_t* alarm_info;
+ bundle *bundle_data;
+ int result;
+
+ if (service == NULL || date == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE)
+ {
+ 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;
+ internal_time.month = date->tm_mon +1;
+ internal_time.day = date->tm_mday;
+
+ internal_time.hour = date->tm_hour;
+ internal_time.min = date->tm_min;
+ internal_time.sec = date->tm_sec;
+
+ result = alarmmgr_set_time(alarm_info,internal_time);
+
+ if (result < 0)
+ {
+ alarmmgr_free_alarm(alarm_info);
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+ }
+
+
+ if (period_in_second > 0)
+ {
+ result = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_REPEAT, period_in_second);
+ }
+ else
+ {
+ result = alarmmgr_set_repeat_mode(alarm_info, ALARM_REPEAT_MODE_ONCE, period_in_second);
+ }
+
+ 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);
+
+ 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;
+}
+
+int alarm_cancel(int alarm_id)
+{
+ int result;
+
+ result = alarmmgr_remove_alarm(alarm_id);
+
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+}
+
+int alarm_cancel_all()
+{
+ int result;
+
+ result = alarmmgr_enum_alarm_ids( _remove_alarm_cb, NULL);
+
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+}
+
+int alarm_foreach_registered_alarm(alarm_registered_alarm_cb callback, void* user_data)
+{
+ int result;
+ bool foreach_break = false;
+
+ if (callback == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ //alarm_registered_alarm_cb_broker
+ alarm_foreach_item_cb_context foreach_cb_context = {
+ .cb = callback,
+ .user_data = user_data,
+ .foreach_break = &foreach_break
+ };
+
+ result = alarmmgr_enum_alarm_ids(alarm_registered_alarm_cb_broker, &foreach_cb_context);
+
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+}
+
+int alarm_get_current_time(struct tm* date)
+{
+ time_t now;
+
+ if (date == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ time(&now);
+ localtime_r(&now, date);
+ return ALARM_ERROR_NONE;
+}
+
+
+int alarm_schedule_with_recurrence_week_flag(service_h service, 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)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", ALARM_ERROR_INVALID_PARAMETER);
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ if (service_to_bundle(service, &bundle_data) != SERVICE_ERROR_NONE)
+ {
+ 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;
+ internal_time.month = date->tm_mon +1;
+ internal_time.day = date->tm_mday;
+
+ internal_time.hour = date->tm_hour;
+ internal_time.min = date->tm_min;
+ internal_time.sec = date->tm_sec;
+
+ result = alarmmgr_set_time(alarm_info,internal_time);
+
+ if (result < 0)
+ {
+ alarmmgr_free_alarm(alarm_info);
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+ }
+
+ if (week_flag > 0)
+ {
+ 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);
+}
+
+int alarm_get_scheduled_recurrence_week_flag(int alarm_id, int *week_flag)
+{
+ alarm_error_t result;
+ alarm_entry_t *entry = NULL;
+ alarm_repeat_mode_t mode;
+ int value;
+
+ if(week_flag == NULL)
+ {
+ 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_repeat_mode(entry, &mode, &value);
+
+ if(mode != ALARM_REPEAT_MODE_WEEKLY)
+ {
+ if (entry != NULL)
+ {
+ alarmmgr_free_alarm(entry);
+ }
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ if(result != ALARMMGR_RESULT_SUCCESS)
+ {
+ if (entry != NULL)
+ {
+ alarmmgr_free_alarm(entry);
+ }
+ return convert_error_code_to_alarm(__FUNCTION__, result);
+ }
+
+ result = alarmmgr_free_alarm(entry);
+ if(result != ALARMMGR_RESULT_SUCCESS)
+ {
+ 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)
+{
+ bundle *b = NULL;
+ int error_code = 0;
+
+ b = alarmmgr_get_alarm_appsvc_info(alarm_id, &error_code);
+
+ if(error_code != ALARMMGR_RESULT_SUCCESS)
+ {
+ return convert_error_code_to_alarm(__FUNCTION__, error_code);
+ }
+
+ if(b == NULL)
+ {
+ return ALARM_ERROR_INVALID_PARAMETER;
+ }
+
+ error_code = service_create_request(b, service);
+
+ if(error_code != SERVICE_ERROR_NONE)
+ {
+ return ALARM_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_free(b);
+
+ return ALARM_ERROR_NONE;
+
+}
diff --git a/src/app_device.c b/src/app_device.c
new file mode 100755
index 0000000..8b6215d
--- /dev/null
+++ b/src/app_device.c
@@ -0,0 +1,83 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <bundle.h>
+#include <appcore-common.h>
+#include <aul.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <app_private.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_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;
+}
+
+app_device_orientation_e app_get_device_orientation(void)
+{
+ enum appcore_rm rm;
+ app_device_orientation_e dev_orientation = APP_DEVICE_ORIENTATION_0;
+
+ if (appcore_get_rotation_state(&rm) == 0)
+ {
+ dev_orientation = app_convert_appcore_rm(rm);
+ }
+
+ return dev_orientation;
+}
+
diff --git a/src/app_error.c b/src/app_error.c
new file mode 100755
index 0000000..b3c8c0c
--- /dev/null
+++ b/src/app_error.c
@@ -0,0 +1,72 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <dlog.h>
+
+#include <app_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION"
+
+static const char* app_error_to_string(app_error_e error)
+{
+ switch (error)
+ {
+ case APP_ERROR_NONE:
+ return "NONE";
+
+ case APP_ERROR_INVALID_PARAMETER:
+ return "INVALID_PARAMETER";
+
+ case APP_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+
+ case APP_ERROR_INVALID_CONTEXT:
+ return "INVALID_CONTEXT";
+
+ case APP_ERROR_NO_SUCH_FILE:
+ return "NO_SUCH_FILE";
+
+ case APP_ERROR_ALREADY_RUNNING:
+ return "ALREADY_RUNNING";
+
+ default :
+ return "UNKNOWN";
+ }
+}
+
+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);
+ }
+ else
+ {
+ LOGE("[%s] %s(0x%08x)", function, app_error_to_string(error), error);
+ }
+
+ return error;
+}
diff --git a/src/app_finalizer.c b/src/app_finalizer.c
new file mode 100755
index 0000000..ae0b41c
--- /dev/null
+++ b/src/app_finalizer.c
@@ -0,0 +1,108 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <app_private.h>
+
+typedef struct _app_finalizer_s_ {
+ app_finalizer_cb callback;
+ void *data;
+ struct _app_finalizer_s_ *next;
+} app_finalizer_s;
+
+typedef app_finalizer_s *app_finalizer_h;
+
+static app_finalizer_s finalizer_head = {
+ .callback = NULL,
+ .data = NULL,
+ .next = NULL
+};
+
+int app_finalizer_add(app_finalizer_cb callback, void *data)
+{
+ app_finalizer_h finalizer_tail = &finalizer_head;
+ app_finalizer_h finalizer_new;
+
+ finalizer_new = malloc(sizeof(app_finalizer_s));
+
+ if (finalizer_new == NULL)
+ {
+ return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+ }
+
+ finalizer_new->callback = callback;
+ finalizer_new->data = data;
+ finalizer_new->next = NULL;
+
+ while (finalizer_tail->next)
+ {
+ finalizer_tail = finalizer_tail->next;
+ }
+
+ finalizer_tail->next = finalizer_new;
+
+ return APP_ERROR_NONE;
+}
+
+int app_finalizer_remove(app_finalizer_cb callback)
+{
+ app_finalizer_h finalizer_node = &finalizer_head;
+
+ while (finalizer_node->next)
+ {
+ if (finalizer_node->next->callback == callback)
+ {
+ app_finalizer_h removed_node = finalizer_node->next;
+ finalizer_node->next = removed_node->next;
+ free(removed_node);
+ return APP_ERROR_NONE;
+ }
+
+ finalizer_node = finalizer_node->next;
+ }
+
+ return APP_ERROR_INVALID_PARAMETER;
+}
+
+void app_finalizer_execute(void)
+{
+ app_finalizer_h finalizer_node = &finalizer_head;
+ app_finalizer_h finalizer_executed;
+ app_finalizer_cb finalizer_cb = NULL;
+
+ if(finalizer_node)
+ finalizer_node = finalizer_node->next;
+
+ while (finalizer_node)
+ {
+ finalizer_cb = finalizer_node->callback;
+
+ finalizer_cb(finalizer_node->data);
+
+ finalizer_executed = finalizer_node;
+
+ finalizer_node = finalizer_node->next;
+
+ free(finalizer_executed);
+ }
+
+ finalizer_head.next = NULL;
+}
+
diff --git a/src/app_main.c b/src/app_main.c
new file mode 100755
index 0000000..81f4f5e
--- /dev/null
+++ b/src/app_main.c
@@ -0,0 +1,401 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <bundle.h>
+#include <appcore-common.h>
+#include <appcore-efl.h>
+#include <aul.h>
+#include <dlog.h>
+
+#include <Elementary.h>
+
+#include <app_private.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION"
+
+typedef enum {
+ APP_STATE_NOT_RUNNING, // The application has been launched or was running but was terminated
+ APP_STATE_CREATING, // The application is initializing the resources on app_create_cb callback
+ APP_STATE_RUNNING, // The application is running in the foreground and background
+} app_state_e;
+
+typedef struct {
+ char *package;
+ char *app_name;
+ app_state_e state;
+ app_event_callback_s *callback;
+ void *data;
+} app_context_s;
+
+typedef app_context_s *app_context_h;
+
+static int app_appcore_create(void *data);
+static int app_appcore_pause(void *data);
+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 void app_set_appcore_event_cb(app_context_h app_context);
+static void app_unset_appcore_event_cb(void);
+
+
+int app_efl_main(int *argc, char ***argv, app_event_callback_s *callback, void *user_data)
+{
+ app_context_s 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 = app_appcore_create,
+ .terminate = app_appcore_terminate,
+ .pause = app_appcore_pause,
+ .resume = app_appcore_resume,
+ .reset = app_appcore_reset,
+ };
+
+ if (argc == NULL || 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)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package's app name");
+ }
+
+ app_context.state = APP_STATE_CREATING;
+
+ 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 app_efl_exit(void)
+{
+ elm_exit();
+}
+
+
+int app_appcore_create(void *data)
+{
+ app_context_h app_context = data;
+ app_create_cb create_cb;
+ char locale_dir[TIZEN_PATH_MAX] = {0, };
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ 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)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "app_create_cb() returns false");
+ }
+
+ app_context->state = APP_STATE_RUNNING;
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_terminate(void *data)
+{
+ app_context_h 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);
+ }
+
+ app_unset_appcore_event_cb();
+
+ app_finalizer_execute();
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_pause(void *data)
+{
+ app_context_h 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;
+}
+
+int app_appcore_resume(void *data)
+{
+ app_context_h 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;
+}
+
+
+int app_appcore_reset(bundle *appcore_bundle, void *data)
+{
+ app_context_h app_context = data;
+ app_service_cb service_cb;
+ service_h service;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ if (service_create_event(appcore_bundle, &service) != APP_ERROR_NONE)
+ {
+ return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a service handle from the bundle");
+ }
+
+ service_cb = app_context->callback->service;
+
+ if (service_cb != NULL)
+ {
+ service_cb(service, app_context->data);
+ }
+
+ service_destroy(service);
+
+ return APP_ERROR_NONE;
+}
+
+
+int app_appcore_low_memory(void *data)
+{
+ app_context_h app_context = data;
+ app_low_memory_cb low_memory_cb;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ low_memory_cb = app_context->callback->low_memory;
+
+ if (low_memory_cb != NULL)
+ {
+ low_memory_cb(app_context->data);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_low_battery(void *data)
+{
+ app_context_h app_context = data;
+ app_low_battery_cb low_battery_cb;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ low_battery_cb = app_context->callback->low_battery;
+
+ if (low_battery_cb != NULL)
+ {
+ low_battery_cb(app_context->data);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_rotation_event(enum appcore_rm rm, void *data)
+{
+ app_context_h app_context = data;
+ app_device_orientation_cb device_orientation_cb;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ device_orientation_cb = app_context->callback->device_orientation;
+
+ if (device_orientation_cb != NULL)
+ {
+ app_device_orientation_e dev_orientation;
+
+ dev_orientation = app_convert_appcore_rm(rm);
+
+ device_orientation_cb(dev_orientation, app_context->data);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_lang_changed(void *data)
+{
+ app_context_h app_context = data;
+ app_language_changed_cb lang_changed_cb;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ lang_changed_cb = app_context->callback->language_changed;
+
+ if (lang_changed_cb != NULL)
+ {
+ lang_changed_cb(app_context->data);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+int app_appcore_region_changed(void *data)
+{
+ app_context_h app_context = data;
+ app_region_format_changed_cb region_changed_cb;
+
+ if (app_context == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ region_changed_cb = app_context->callback->region_format_changed;
+
+ if (region_changed_cb != NULL)
+ {
+ region_changed_cb(app_context->data);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+
+void app_set_appcore_event_cb(app_context_h app_context)
+{
+ if (app_context->callback->low_memory != NULL)
+ {
+ appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, app_appcore_low_memory, app_context);
+ }
+
+ if (app_context->callback->low_battery != NULL)
+ {
+ appcore_set_event_callback(APPCORE_EVENT_LOW_BATTERY, app_appcore_low_battery, app_context);
+ }
+
+ if (app_context->callback->device_orientation != NULL)
+ {
+ appcore_set_rotation_cb(app_appcore_rotation_event, app_context);
+ }
+
+ if (app_context->callback->language_changed != NULL)
+ {
+ appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, app_appcore_lang_changed, app_context);
+ }
+
+ if (app_context->callback->region_format_changed != NULL)
+ {
+ appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, app_appcore_region_changed, app_context);
+ }
+}
+
+void 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);
+ appcore_unset_rotation_cb();
+ appcore_set_event_callback(APPCORE_EVENT_LANG_CHANGE, NULL, NULL);
+ appcore_set_event_callback(APPCORE_EVENT_REGION_CHANGE, NULL, NULL);
+}
diff --git a/src/app_package.c b/src/app_package.c
new file mode 100755
index 0000000..56893a1
--- /dev/null
+++ b/src/app_package.c
@@ -0,0 +1,188 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <bundle.h>
+#include <appcore-common.h>
+#include <aul.h>
+#include <ail.h>
+#include <dlog.h>
+
+#include <app_private.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION"
+
+int app_get_package_app_name(const char *appid, char **name)
+{
+ char *name_token = NULL;
+
+ if (appid == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ // com.vendor.name -> name
+ name_token = strrchr(appid, '.');
+
+ if (name_token == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, NULL);
+ }
+
+ name_token++;
+
+ *name = strdup(name_token);
+
+ if (*name == NULL)
+ {
+ return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+int app_get_package(char **package)
+{
+ return app_get_id(package);
+}
+
+int app_get_id(char **id)
+{
+ static char id_buf[TIZEN_PATH_MAX] = {0, };
+ int ret = -1;
+
+ if (id == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ if (id_buf[0] == '\0')
+ {
+ 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')
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the application ID");
+ }
+
+ *id = strdup(id_buf);
+
+ if (*id == NULL)
+ {
+ return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+ }
+
+ return APP_ERROR_NONE;
+}
+
+static int app_get_appinfo(const char *package, const char *property, char **value)
+{
+ ail_appinfo_h appinfo;
+ char *appinfo_value;
+ char *appinfo_value_dup;
+
+ 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_destroy_appinfo(appinfo);
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get app-property");
+ }
+
+ appinfo_value_dup = strdup(appinfo_value);
+
+ ail_destroy_appinfo(appinfo);
+
+ if (appinfo_value_dup == NULL)
+ {
+ return app_error(APP_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
+ }
+
+ *value = appinfo_value_dup;
+
+ return APP_ERROR_NONE;
+}
+
+int app_get_name(char **name)
+{
+ char *package = NULL;
+ int retval;
+
+ if(name == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ if (app_get_id(&package) != 0)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
+ }
+
+ retval = app_get_appinfo(package, AIL_PROP_NAME_STR, name);
+
+ if (package != NULL)
+ {
+ free(package);
+ }
+
+ return retval;
+}
+
+int app_get_version(char **version)
+{
+ char *package;
+ int retval;
+
+ if(version == NULL)
+ {
+ return app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ if (app_get_id(&package) != 0)
+ {
+ return app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
+ }
+
+ retval = app_get_appinfo(package, AIL_PROP_VERSION_STR, version);
+
+ if (package != NULL)
+ {
+ free(package);
+ }
+
+ return retval;
+}
+
diff --git a/src/app_resource.c b/src/app_resource.c
new file mode 100755
index 0000000..a3c2da5
--- /dev/null
+++ b/src/app_resource.c
@@ -0,0 +1,250 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <bundle.h>
+#include <appcore-common.h>
+#include <appcore-efl.h>
+#include <aul.h>
+#include <dlog.h>
+#include <ail.h>
+
+#include <app_private.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION"
+
+static const char *INSTALLED_PATH = "/opt/usr/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 *appid = NULL;
+ char root_directory[TIZEN_PATH_MAX] = {0, };
+ char bin_directory[TIZEN_PATH_MAX] = {0, };
+ ail_appinfo_h ail_app_info;
+ char *pkgid;
+
+ if (app_get_id(&appid) != APP_ERROR_NONE)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the appid");
+ return NULL;
+ }
+
+ if (ail_get_appinfo(appid, &ail_app_info) != AIL_ERROR_OK)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the appinfo");
+ free(appid);
+ return NULL;
+ }
+
+ if (ail_appinfo_get_str(ail_app_info, AIL_PROP_X_SLP_PKGID_STR, &pkgid) != AIL_ERROR_OK)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the pkgid");
+ free(appid);
+ ail_destroy_appinfo(ail_app_info);
+ return NULL;
+ }
+
+ if(pkgid)
+ {
+ free(appid);
+ appid = strdup(pkgid);
+ }
+
+ ail_destroy_appinfo(ail_app_info);
+
+ snprintf(root_directory, sizeof(root_directory), "%s/%s", INSTALLED_PATH, appid);
+ 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, appid);
+ }
+
+ free(appid);
+
+ 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)
+{
+ 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;
+}
+
+char* app_get_data_directory(char *buffer, int size)
+{
+ static char data_directory[TIZEN_PATH_MAX] = {0, };
+ static int data_directory_length = 0;
+ ail_appinfo_h ail_app_info;
+ char *pkgid;
+
+ if (data_directory[0] == '\0')
+ {
+ char *root_directory = NULL;
+ char *appid = 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_id(&appid) != APP_ERROR_NONE)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
+ free(root_directory);
+ return NULL;
+ }
+
+ if (ail_get_appinfo(appid, &ail_app_info) != AIL_ERROR_OK)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
+ free(root_directory);
+ free(appid);
+ return NULL;
+ }
+
+ if (ail_appinfo_get_str(ail_app_info, AIL_PROP_X_SLP_PKGID_STR, &pkgid) != AIL_ERROR_OK)
+ {
+ app_error(APP_ERROR_INVALID_CONTEXT, __FUNCTION__, "failed to get the package");
+ free(root_directory);
+ free(appid);
+ ail_destroy_appinfo(ail_app_info);
+ return NULL;
+ }
+
+ if(pkgid)
+ {
+ free(appid);
+ appid = strdup(pkgid);
+ }
+
+ ail_destroy_appinfo(ail_app_info);
+
+ snprintf(root_directory, TIZEN_PATH_MAX, "%s/%s", INSTALLED_PATH, appid);
+
+ free(appid);
+
+ 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;
+}
+
+char* app_get_resource(const char *resource, char *buffer, int size)
+{
+ 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;
+}
+
+
+void app_set_reclaiming_system_cache_on_pause(bool enable)
+{
+ appcore_set_system_resource_reclaiming(enable);
+}
+
diff --git a/src/i18n.c b/src/i18n.c
new file mode 100755
index 0000000..a1ca9e3
--- /dev/null
+++ b/src/i18n.c
@@ -0,0 +1,29 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <app_i18n.h>
+
+char* i18n_get_text(const char *message)
+{
+ return gettext(message);
+}
+
diff --git a/src/preference.c b/src/preference.c
new file mode 100755
index 0000000..ad85562
--- /dev/null
+++ b/src/preference.c
@@ -0,0 +1,758 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sqlite3.h>
+
+#include <app_private.h>
+
+#include <app_preference.h>
+#include <app_preference_private.h>
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_PREFERENCE"
+#define DBG_MODE (1)
+
+static sqlite3 *pref_db = NULL;
+static bool is_update_hook_registered = false;
+static pref_changed_cb_node_t *head = NULL;
+
+static void _finish(void *data)
+{
+ if (pref_db != NULL)
+ {
+ sqlite3_close(pref_db);
+ pref_db = NULL;
+ }
+}
+
+static int _initialize(void)
+{
+ char data_path[TIZEN_PATH_MAX] = {0, };
+ char db_path[TIZEN_PATH_MAX] = {0, };
+ int ret;
+ char *errmsg;
+
+ if (app_get_data_directory(data_path, sizeof(data_path)) == NULL)
+ {
+ 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);
+
+ ret = sqlite3_open(db_path, &pref_db);
+ if (ret != SQLITE_OK)
+ {
+ 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_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("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;
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ app_finalizer_add(_finish, NULL);
+
+ 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;
+ bool exist = false;
+
+ if (key == NULL || key[0] == '\0' || data == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+
+ /* insert data or update data if data already exist */
+ ret = preference_is_existing(key, &exist);
+ if (ret != PREFERENCE_ERROR_NONE)
+ {
+ return ret;
+ }
+
+ // 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);
+ }
+ 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);
+ }
+
+ if (buf == NULL)
+ {
+ 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("IO_ERROR(0x%08x): fail to write data(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
+ sqlite3_free(errmsg);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+//static int _read_data(const char *key, preference_type_e *type, char *data)
+static int _read_data(const char *key, char *type, char *data)
+{
+ int ret;
+ char *buf;
+ char **result;
+ int rows;
+ int columns;
+ char *errmsg;
+
+ if (key == NULL || key[0] == '\0' || data == 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("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';",
+ PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key);
+
+ if (buf == NULL)
+ {
+ LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
+ sqlite3_free(buf);
+ if (ret != SQLITE_OK)
+ {
+ 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("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
+ sqlite3_free_table(result);
+ return PREFERENCE_ERROR_NO_KEY;
+ }
+
+ snprintf(type, 2, "%s", result[4]); // get type value
+ snprintf(data, BUF_LEN, "%s", result[5]); // get data value
+
+ sqlite3_free_table(result);
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+
+int preference_set_int(const char *key, int value)
+{
+ char type[2];
+ char data[BUF_LEN];
+ snprintf(type, 2, "%d", PREFERENCE_TYPE_INT);
+ snprintf(data, BUF_LEN, "%d", value);
+ return _write_data(key, type, data);
+}
+
+int preference_get_int(const char *key, int *value)
+{
+ char type[2];
+ char data[BUF_LEN];
+ int ret;
+
+ ret = _read_data(key, type, data);
+ if (ret == PREFERENCE_ERROR_NONE)
+ {
+ if (atoi(type) == PREFERENCE_TYPE_INT)
+ {
+ *value = atoi(data);
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ return ret;
+}
+
+int preference_set_double(const char *key, double value)
+{
+ char type[2];
+ char data[BUF_LEN];
+ snprintf(type, 2, "%d", PREFERENCE_TYPE_DOUBLE);
+ snprintf(data, BUF_LEN, "%f", value);
+ return _write_data(key, type, data);
+}
+
+int preference_get_double(const char *key, double *value)
+{
+ char type[2];
+ char data[BUF_LEN];
+
+ int ret;
+
+ ret = _read_data(key, type, data);
+ if (ret == PREFERENCE_ERROR_NONE)
+ {
+ if (atoi(type) == PREFERENCE_TYPE_DOUBLE)
+ {
+ *value = atof(data);
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ return ret;
+}
+
+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("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+ return _write_data(key, type, value);
+}
+
+int preference_get_string(const char *key, char **value)
+{
+ char type[2];
+ 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)
+ {
+ if (atoi(type) == PREFERENCE_TYPE_STRING)
+ {
+ *value = strdup(data);
+ if (value == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
+ return PREFERENCE_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ return ret;
+}
+
+int preference_set_boolean(const char *key, bool value)
+{
+ char type[2];
+ char data[BUF_LEN];
+ snprintf(type, 2, "%d", PREFERENCE_TYPE_BOOLEAN);
+ snprintf(data, BUF_LEN, "%d", value);
+ return _write_data(key, type, data);
+}
+
+int preference_get_boolean(const char *key, bool *value)
+{
+ char type[2];
+ char data[BUF_LEN];
+
+ int ret;
+
+ ret = _read_data(key, type, data);
+ if (ret == PREFERENCE_ERROR_NONE)
+ {
+ if (atoi(type) == PREFERENCE_TYPE_BOOLEAN)
+ {
+ *value = (bool)atoi(data);
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ return ret;
+}
+
+
+// TODO: below operation is too heavy, let's find the light way to check.
+int preference_is_existing(const char *key, bool *exist)
+{
+ int ret;
+ char *buf;
+ char **result;
+ int rows;
+ int columns;
+ char *errmsg;
+
+ if (key == NULL || key[0] == '\0' || exist == 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("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);
+
+ if (buf == NULL)
+ {
+ LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
+ sqlite3_free(buf);
+ if (ret != SQLITE_OK)
+ {
+ 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)
+ {
+ *exist = true;
+ }
+ else
+ {
+ *exist = false;
+ }
+
+ sqlite3_free_table(result);
+ return PREFERENCE_ERROR_NONE;
+}
+
+static pref_changed_cb_node_t* _find_node(const char *key)
+{
+ pref_changed_cb_node_t *tmp_node;
+
+ if (key == NULL || key[0] == '\0' )
+ {
+ return NULL;
+ }
+
+ tmp_node = head;
+
+ while (tmp_node)
+ {
+ if (strcmp(tmp_node->key, key) == 0)
+ {
+ break;
+ }
+ tmp_node = tmp_node->next;
+ }
+
+ return tmp_node;
+}
+
+
+static int _add_node(const char *key, preference_changed_cb cb, void *user_data)
+{
+ pref_changed_cb_node_t *tmp_node;
+
+ if (key == NULL || key[0] == '\0' || cb == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+
+ tmp_node = _find_node(key);
+
+ if (tmp_node != NULL)
+ {
+ tmp_node->cb = cb;
+ tmp_node->user_data = user_data;
+ }
+ else
+ {
+ tmp_node = (pref_changed_cb_node_t*)malloc(sizeof(pref_changed_cb_node_t));
+ if (tmp_node == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
+ return PREFERENCE_ERROR_OUT_OF_MEMORY;
+ }
+
+ tmp_node->key = strdup(key);
+ if (tmp_node->key == NULL)
+ {
+ free(tmp_node);
+ LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
+ return PREFERENCE_ERROR_OUT_OF_MEMORY;
+ }
+ tmp_node->cb = cb;
+ tmp_node->user_data = user_data;
+ tmp_node->prev = NULL;
+ tmp_node->next = head;
+ head = tmp_node;
+ }
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+static int _remove_node(const char *key)
+{
+ pref_changed_cb_node_t *tmp_node;
+
+ if (key == NULL || key[0] == '\0' )
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
+ return PREFERENCE_ERROR_INVALID_PARAMETER;
+ }
+
+ tmp_node = _find_node(key);
+
+ if (tmp_node == NULL)
+ {
+ return PREFERENCE_ERROR_NONE;
+ }
+
+ if (tmp_node->prev != NULL)
+ {
+ tmp_node->prev->next = tmp_node->next;
+ }
+ else
+ {
+ head = tmp_node->next;
+ }
+
+ if (tmp_node->next != NULL)
+ {
+ tmp_node->next->prev = tmp_node->prev;
+ }
+
+ if (tmp_node->key)
+ {
+ free(tmp_node->key);
+ }
+
+ free(tmp_node);
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+
+static void _remove_all_node(void)
+{
+ pref_changed_cb_node_t *tmp_node;
+
+ while (head)
+ {
+ tmp_node = head;
+ head = tmp_node->next;
+
+ if (tmp_node->key)
+ {
+ free(tmp_node->key);
+ }
+
+ free(tmp_node);
+ }
+}
+
+
+static void _update_cb(void *data, int action, char const *db_name, char const *table_name, sqlite_int64 rowid)
+{
+ int ret;
+ char *buf;
+ char **result;
+ int rows;
+ int columns;
+ char *errmsg;
+ pref_changed_cb_node_t *tmp_node;
+
+ // skip INSERT/DELETE event
+ if (action != SQLITE_UPDATE)
+ {
+ return;
+ }
+
+ if (strcmp(table_name, PREF_TBL_NAME) != 0)
+ {
+ LOGI("given table name (%s) is not same", table_name);
+ return;
+ }
+
+ buf = sqlite3_mprintf("SELECT %s FROM %s WHERE rowid='%lld';", PREF_F_KEY_NAME, PREF_TBL_NAME, rowid);
+ if (buf == NULL)
+ {
+ return;
+ }
+ ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
+ sqlite3_free(buf);
+ if (ret != SQLITE_OK)
+ {
+ LOGI("fail to read data(%s)", errmsg);
+ sqlite3_free(errmsg);
+ return;
+ }
+
+ if (rows == 0)
+ {
+ sqlite3_free_table(result);
+ return;
+ }
+
+ tmp_node = _find_node(result[1]);
+
+ if (tmp_node != NULL && tmp_node->cb != NULL)
+ {
+ tmp_node->cb(result[1], tmp_node->user_data);
+ }
+
+ sqlite3_free_table(result);
+}
+
+
+int preference_remove(const char *key)
+{
+ int ret;
+ char *buf;
+ char *errmsg;
+ bool exist;
+
+ ret = preference_is_existing(key, &exist);
+ if (ret != PREFERENCE_ERROR_NONE)
+ {
+ return ret;
+ }
+
+ if (!exist)
+ {
+ return PREFERENCE_ERROR_NONE;
+ }
+
+ /* insert data or update data if data already exist */
+ buf = sqlite3_mprintf("DELETE FROM %s WHERE %s = '%s';",
+ PREF_TBL_NAME, PREF_F_KEY_NAME, key);
+
+ if (buf == NULL)
+ {
+ 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("IO_ERROR(0x%08x) : fail to delete data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
+ sqlite3_free(errmsg);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ // if exist, remove changed cb
+ _remove_node(key);
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+
+int preference_remove_all(void)
+{
+ int ret;
+ char *buf;
+ char *errmsg;
+
+ if (pref_db == NULL)
+ {
+ if (_initialize() != PREFERENCE_ERROR_NONE)
+ {
+ LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+ }
+
+ /* insert data or update data if data already exist */
+ buf = sqlite3_mprintf("DELETE FROM %s;", PREF_TBL_NAME);
+ if (buf == NULL)
+ {
+ 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("IO_ERROR(0x%08x) : fail to delete data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
+ sqlite3_free(errmsg);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ // if exist, remove changed cb
+ _remove_all_node();
+
+ return PREFERENCE_ERROR_NONE;
+}
+
+
+int preference_set_changed_cb(const char *key, preference_changed_cb callback, void *user_data)
+{
+ int ret;
+ bool exist;
+
+ ret = preference_is_existing(key, &exist);
+ if (ret != PREFERENCE_ERROR_NONE)
+ {
+ 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;
+ }
+
+ if (!is_update_hook_registered)
+ {
+ sqlite3_update_hook(pref_db, _update_cb, NULL);
+ is_update_hook_registered = true;
+ }
+
+ return _add_node(key, callback, user_data);
+}
+
+int preference_unset_changed_cb(const char *key)
+{
+ if (pref_db == NULL)
+ {
+ if (_initialize() != PREFERENCE_ERROR_NONE)
+ {
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+ }
+
+ return _remove_node(key);
+}
+
+int preference_foreach_item(preference_item_cb callback, void *user_data)
+{
+ int ret;
+ char *buf;
+ char **result;
+ int rows;
+ int columns;
+ char *errmsg;
+ int i;
+
+ if (pref_db == NULL)
+ {
+ if (_initialize() != PREFERENCE_ERROR_NONE)
+ {
+ LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+ }
+
+ if (callback == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", 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("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
+ sqlite3_free(buf);
+ if (ret != SQLITE_OK)
+ {
+ LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
+ sqlite3_free(errmsg);
+ return PREFERENCE_ERROR_IO_ERROR;
+ }
+
+ for (i = 1; i <= rows; i++)
+ {
+ if (callback(result[i], user_data) != true)
+ {
+ break;
+ }
+ }
+
+ sqlite3_free_table(result);
+
+ return PREFERENCE_ERROR_NONE;
+}
+
diff --git a/src/service.c b/src/service.c
new file mode 100755
index 0000000..73196b1
--- /dev/null
+++ b/src/service.c
@@ -0,0 +1,1285 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <bundle.h>
+#include <aul.h>
+#include <appsvc.h>
+#include <dlog.h>
+
+#include <app_service.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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";
+
+ case SERVICE_ERROR_LAUNCH_REJECTED:
+ return "LAUNCH_REJECTED";
+
+ 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_category(service_h service, const char *category)
+{
+ if (service_valiate_service(service))
+ {
+ return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ if (category != NULL)
+ {
+ if (appsvc_set_category(service->data, category) != 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_category(service_h service, char **category)
+{
+ const char *category_value;
+
+ if (service_valiate_service(service) || category == NULL)
+ {
+ return service_error(SERVICE_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
+ }
+
+ category_value = appsvc_get_category(service->data);
+
+ if (category_value != NULL)
+ {
+ *category = strdup(category_value);
+ }
+ else
+ {
+ *category = 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_appid(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_appid(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 *appid;
+
+ 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;
+ }
+
+ appid = appsvc_get_appid(service->data);
+
+ // operation : default
+ if (!strcmp(operation, SERVICE_OPERATION_DEFAULT))
+ {
+ if (appid == 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)
+ {
+ if (launch_pid == APPSVC_RET_ENOMATCH)
+ {
+ return service_error(SERVICE_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
+ }
+ else
+ {
+ return service_error(SERVICE_ERROR_LAUNCH_REJECTED, __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; i<array_data_length; i++)
+ {
+ if (array_data[i] != NULL)
+ {
+ array_data_clone[i] = strdup(array_data[i]);
+ }
+ }
+
+ *value = array_data_clone;
+ *length = array_data_length;
+
+ return SERVICE_ERROR_NONE;
+}
+
+
+int service_is_extra_data_array(service_h service, const char *key, bool *array)
+{
+ if (service_valiate_service(service) || service_validate_extra_data(key) || array == 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");
+ }
+
+ if (!appsvc_data_is_array(service->data, 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_appid_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
new file mode 100755
index 0000000..a6f9202
--- /dev/null
+++ b/src/storage.c
@@ -0,0 +1,397 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/vfs.h>
+
+#include <aul.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <app_storage.h>
+#include <app_storage_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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("failed to register device : not enough device table");
+ 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("INVALID_PARAMETER(0x%08x) : invalid callback", 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("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ get_state = storage_info->device->get_state;
+
+ if (get_state == NULL)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("INVALID_PARAMETER(0x%08x) : invalid storage information", 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("INVALID_PARAMETER(0x%08x) : invalid callback", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ if (set_state_cb(storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ get_space = storage_info->device->get_space;
+
+ if (get_space == NULL)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ if (get_space(bytes, NULL) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
+ return STORAGE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (storage_get_storage(storage, &storage_info) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ get_space = storage_info->device->get_space;
+
+ if (get_space == NULL)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
+ return STORAGE_ERROR_NOT_SUPPORTED;
+ }
+
+ if (get_space(NULL, bytes) != 0)
+ {
+ LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", 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("statfs returns error(%d) directory(%s)\n", 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
new file mode 100755
index 0000000..c9e0b6d
--- /dev/null
+++ b/src/storage_internal.c
@@ -0,0 +1,79 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/vfs.h>
+
+#include <aul.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <app_storage.h>
+#include <app_storage_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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("OUT_OF_MEMORY(0x%08x)", 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
new file mode 100755
index 0000000..9dd9cb0
--- /dev/null
+++ b/src/storage_sdcard.c
@@ -0,0 +1,125 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/vfs.h>
+
+#include <aul.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <app_storage.h>
+#include <app_storage_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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("OUT_OF_MEMORY(0x%08x)", 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
new file mode 100755
index 0000000..aba65c0
--- /dev/null
+++ b/src/storage_usbhost.c
@@ -0,0 +1,125 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/vfs.h>
+
+#include <aul.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <app_storage.h>
+#include <app_storage_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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_SYSMAN_USB_HOST_DISCONNECTED:
+ return STORAGE_STATE_REMOVED;
+
+ case VCONFKEY_SYSMAN_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("OUT_OF_MEMORY(0x%08x)", 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
new file mode 100755
index 0000000..1610d02
--- /dev/null
+++ b/src/ui_notification.c
@@ -0,0 +1,1179 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <dlog.h>
+#include <notification.h>
+
+#include <app.h>
+#include <app_service_private.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "CAPI_APPFW_APPLICATION_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("INVALID_PARAMETER(0x%08x) : invalid output param", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x) : invalid output param", 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("OUT_OF_MEMORY(0x%08x)", 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)
+ {
+ free(notification_out);
+ 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x) : invalid handle", 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_get_id(ui_notification_h notification, int *id)
+{
+ notification_h raw_handle = NULL;
+
+ if (notification == NULL || id == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+ if (notification->raw_handle == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ raw_handle = notification->raw_handle;
+ if (notification_get_id(raw_handle, NULL, id) != NOTIFICATION_ERROR_NONE) {
+ LOGE("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+ return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (notification->raw_handle != NULL)
+ {
+ retcode = notification_clone(notification->raw_handle, &(notification_out->raw_handle));
+
+ if (retcode)
+ {
+ free(notification_out);
+ 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("INVALID_PARAMETER(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (path != NULL)
+ {
+ path_dup = strdup(path);
+
+ if (path_dup == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (title != NULL)
+ {
+ title_dup = strdup(title);
+
+ if (title_dup == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (content != NULL)
+ {
+ content_dup = strdup(content);
+
+ if (content_dup == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+ return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : invalid service handle", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", UI_NOTIFICATION_ERROR_OUT_OF_MEMORY);
+ return UI_NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+ else
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : invalid service handle", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (path != NULL)
+ {
+ path_dup = strdup(path);
+
+ if (path_dup == NULL)
+ {
+ LOGE("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", 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("INVALID_PARAMETER(0x%08x) : invalid handle", 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("NO_SUCH_FILE(0x%08x) : invalid icon", 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("NO_SUCH_FILE(0x%08x) : invalid sound file", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->posted == true)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was already posted", 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("OUT_OF_MEMORY(0x%08x)", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->posted == false)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
+ return UI_NOTIFICATION_ERROR_INVALID_STATE;
+ }
+
+ if (notification->removed == true)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->raw_handle == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->posted == false)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
+ return UI_NOTIFICATION_ERROR_INVALID_STATE;
+ }
+
+ if (notification->removed == true)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", UI_NOTIFICATION_ERROR_INVALID_STATE);
+ return UI_NOTIFICATION_ERROR_INVALID_STATE;
+ }
+
+ if (value < 0)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : the value must be greater than or equal to zero.", 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("INVALID_PARAMETER(0x%08x) : invalid progress type", 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->raw_handle == NULL)
+ {
+ LOGE("INVALID_PARAMETER(0x%08x) : invalid handle", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification->posted == false)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was not posted", UI_NOTIFICATION_ERROR_INVALID_STATE);
+ return UI_NOTIFICATION_ERROR_INVALID_STATE;
+ }
+
+ if (notification->removed == true)
+ {
+ LOGE("INVALID_STATE(0x%08x) : the notification was canceled or cleared", 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("INVALID_PARAMETER(0x%08x)", 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;
+ char cmdline[512] = {0,};
+ char buf[64] = {0,};
+
+ if (notification_get_pkgname(handle, &handle_package))
+ {
+ return false;
+ }
+
+ if (app_get_package(&package))
+ {
+ int ret = 0;
+ int fd = -1;
+ int pid = getpid();
+
+ snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ return false;
+ }
+
+ ret = read(fd, cmdline, sizeof(cmdline) - 1);
+ if (ret <= 0) {
+ close(fd);
+ return false;
+ }
+
+ cmdline[ret] = 0;
+ close(fd);
+
+ if (strlen(cmdline) == strlen(handle_package))
+ {
+ if (!strncmp(cmdline, handle_package, strlen(cmdline)))
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ 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("INVALID_PARAMETER(0x%08x)", UI_NOTIFICATION_ERROR_INVALID_PARAMETER);
+ return UI_NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ if (notification_get_grouping_list(notification_type, -1, &raw_handle_list))
+ {
+ LOGE("DB_FAILED(0x%08x) : failed to get a notification list", 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, &notification))
+ {
+ 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;
+}
+