/* * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include "alarm.h" #include "alarm-internal.h" static int __dbus_call_sync(GDBusProxy *proxy, const gchar *method_name, GVariant *param, GVariant **reply) { int error_code = ALARMMGR_RESULT_SUCCESS; GError *error = NULL; *reply = g_dbus_proxy_call_sync(proxy, method_name, param, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { if (error->code == G_DBUS_ERROR_ACCESS_DENIED) error_code = ERR_ALARM_NO_PERMISSION; else error_code = ERR_ALARM_SYSTEM_FAIL; LOGE("%s : g_dbus_proxy_call_sync() failed.\ error_code[%d]. error->message is %s(%d)", method_name, error_code, error->message, error->code); g_error_free(error); } return error_code; } bool _send_alarm_create_noti(alarm_context_t context, base_info_t *base_info, alarm_id_t *alarm_id, notification_h noti, int *error_code) { int return_code = -1; GVariant *noti_gv = NULL; char *noti_data; guchar *data; int datalen = 0; GVariant *param = NULL; GVariant *reply = NULL; noti_gv = notification_ipc_make_gvariant_from_noti(noti, true); if (!noti_gv) { if (error_code) *error_code = ERR_ALARM_SYSTEM_FAIL; return false; } datalen = g_variant_get_size(noti_gv); if (datalen < 0) return false; data = malloc(datalen); if (!data) return false; g_variant_store(noti_gv, data); noti_data = g_base64_encode((guchar *)data, datalen); param = g_variant_new("(iiiiiiiiiixiixs)", base_info->start.year, base_info->start.month, base_info->start.day, base_info->start.hour, base_info->start.min, base_info->start.sec, base_info->end.year, base_info->end.month, base_info->end.day, base_info->mode.u_interval.day_of_week, (gint64)base_info->mode.u_interval.interval, base_info->mode.repeat, base_info->alarm_type, (gint64)base_info->reserved_info, (char *)noti_data); if (noti_data) free(noti_data); if (data) free(data); g_variant_unref(noti_gv); return_code = __dbus_call_sync(context.proxy, "alarm_create_noti", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(ii)", alarm_id, &return_code); LOGD("alarm_create_noti() success. alarm_id[%d], return_code[%d].", *alarm_id, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_create_appsvc(alarm_context_t context, base_info_t *base_info, alarm_id_t *alarm_id, bundle *b, int *error_code) { int return_code = -1; bundle_raw *b_data = NULL; int datalen = 0; GVariant *param = NULL; GVariant *reply = NULL; if (bundle_encode(b, &b_data, &datalen)) { LOGE("Unable to encode the bundle data\n"); if (error_code) *error_code = ERR_ALARM_SYSTEM_FAIL; return false; } param = g_variant_new("(iiiiiiiiiixiixs)", base_info->start.year, base_info->start.month, base_info->start.day, base_info->start.hour, base_info->start.min, base_info->start.sec, base_info->end.year, base_info->end.month, base_info->end.day, base_info->mode.u_interval.day_of_week, (gint64)base_info->mode.u_interval.interval, base_info->mode.repeat, base_info->alarm_type, (gint64)base_info->reserved_info, (char *)b_data); if (b_data) free(b_data); return_code = __dbus_call_sync(context.proxy, "alarm_create_appsvc", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(ii)", alarm_id, &return_code); LOGD("alarm_create_appsvc() success. alarm_id[%d], return_code[%d].", *alarm_id, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_create(alarm_context_t context, base_info_t *base_info, alarm_id_t *alarm_id, const char *dst_service_name, const char *dst_service_name_mod, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; /*TODO: Dbus bus name validation is must & will be added to avoid alarm-server crash*/ if (context.app_service_name == NULL && strlen(dst_service_name) == 4 && strcmp(dst_service_name, "null") == 0) { LOGE("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); if (error_code) *error_code = ERR_ALARM_INVALID_PARAM; return false; } param = g_variant_new("(ssiiiiiiiiiiiiixss)", context.app_service_name, context.app_service_name_mod, base_info->start.year, base_info->start.month, base_info->start.day, base_info->start.hour, base_info->start.min, base_info->start.sec, base_info->msec, base_info->end.year, base_info->end.month, base_info->end.day, base_info->mode.u_interval.day_of_week, base_info->mode.repeat, base_info->alarm_type, (gint64)base_info->reserved_info, dst_service_name, dst_service_name_mod); return_code = __dbus_call_sync(context.proxy, "alarm_create", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(ii)", alarm_id, &return_code); LOGD("alarm_create() dbus sync success. alarm_id[%d], return_code[%d].", *alarm_id, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_create_periodic(alarm_context_t context, int interval, int is_ref, int method, alarm_id_t *alarm_id, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; if (context.app_service_name == NULL) { LOGE("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); if (error_code) *error_code = ERR_ALARM_INVALID_PARAM; return false; } param = g_variant_new("(ssiii)", context.app_service_name, context.app_service_name_mod, interval, is_ref, method); return_code = __dbus_call_sync(context.proxy, "alarm_create_periodic", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(ii)", alarm_id, &return_code); LOGD("alarm_create_periodic() dbus sync success. alarm_id[%d], return_code[%d].", *alarm_id, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bundle *_send_alarm_get_appsvc_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) { int return_code = -1; bundle *b = NULL; gchar *b_data = NULL; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_get_appsvc_info", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(si)", &b_data, &return_code); LOGD("alarm_get_appsvc_info() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; } else { b = bundle_decode((bundle_raw *)b_data, strlen(b_data)); } if (b_data) g_free(b_data); g_variant_unref(reply); return b; } notification_h _send_alarm_get_noti_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) { int return_code = -1; gsize datalen; GVariant *noti_gv = NULL; GVariant *body = NULL; notification_h noti = NULL; gchar *noti_data = NULL; guchar *data; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_get_noti_info", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(si)", ¬i_data, &return_code); LOGD("alarm_get_noti_info() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; } else { data = g_base64_decode(noti_data, &datalen); noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"), data, datalen, TRUE, NULL, NULL); g_variant_get(noti_gv, "(v)", &body); noti = notification_create(NOTIFICATION_TYPE_NOTI); notification_ipc_make_noti_from_gvariant(noti, body); g_free(data); g_variant_unref(noti_gv); } if (noti_data) g_free(noti_data); g_variant_unref(reply); return noti; } bool _send_alarm_set_rtc_time(alarm_context_t context, alarm_date_t *time, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(iiiiii)", time->year, time->month, time->day, time->hour, time->min, time->sec); return_code = __dbus_call_sync(context.proxy, "alarm_set_rtc_time", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_set_rtc_time() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_delete(alarm_context_t context, alarm_id_t alarm_id, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_delete", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_delete() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_delete_all(alarm_context_t context, int *error_code) { int return_code = -1; GVariant *reply = NULL; return_code = __dbus_call_sync(context.proxy, "alarm_delete_all", NULL, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_delete_all() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_get_list_of_ids(alarm_context_t context, int maxnum_of_ids, GVariantIter **iter, int *num_of_ids, int *error_code) { int return_code = -1; GVariantIter *iter_temp = NULL; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(i)", maxnum_of_ids); return_code = __dbus_call_sync(context.proxy, "alarm_get_list_of_ids", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(a(i)ii)", &iter_temp, num_of_ids, &return_code); LOGD("alarm_get_list_of_ids() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_iter_free(iter_temp); g_variant_unref(reply); return false; } *iter = iter_temp; g_variant_unref(reply); return true; } bool _send_alarm_get_number_of_ids(alarm_context_t context, int *num_of_ids, int *error_code) { int return_code = -1; GVariant *reply = NULL; return_code = __dbus_call_sync(context.proxy, "alarm_get_number_of_ids", NULL, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(ii)", num_of_ids, &return_code); LOGD("alarm_get_number_of_ids() dbus sync success.\ num_of_ids[%d] return_code[%d].", *num_of_ids, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_get_info(alarm_context_t context, alarm_id_t alarm_id, base_info_t *base_info, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; gint64 tmp_reserved_info; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_get_info", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(iiiiiiiiiiiixi)", &base_info->start.year, &base_info->start.month, &base_info->start.day, &base_info->start.hour, &base_info->start.min, &base_info->start.sec, &base_info->end.year, &base_info->end.month, &base_info->end.day, &base_info->mode.u_interval.day_of_week, &base_info->mode.repeat, &base_info->alarm_type, &tmp_reserved_info, &return_code); base_info->reserved_info = (time_t)tmp_reserved_info; LOGD("alarm_get_info() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_get_next_duetime(alarm_context_t context, alarm_id_t alarm_id, time_t *duetime, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; gint64 _duetime = 0; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_get_next_duetime", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(xi)", &_duetime, &return_code); LOGD("alarm_get_next_duetime() dbus sync success. return_code[%d].", return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } *duetime = (time_t)_duetime; g_variant_unref(reply); return true; } bool _send_alarm_get_all_info(alarm_context_t context, char **db_path, int *error_code) { int return_code = -1; GVariant *reply = NULL; char *_db_path = NULL; return_code = __dbus_call_sync(context.proxy, "alarm_get_all_info", NULL, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(si)", &_db_path, &return_code); LOGD("alarm_get_all_info() dbus sync success. db_path[%s] return_code[%d].", *db_path, return_code); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } *db_path = _db_path; g_variant_unref(reply); return true; } bool _send_alarm_set_time(alarm_context_t context, time_t new_time, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(x)", (gint64)new_time); return_code = __dbus_call_sync(context.proxy, "alarm_set_time", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_set_time() dbus sync success. return_code[%d].", return_code); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } static void _alarm_set_time_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { int return_code = -1; GError *error = NULL; GVariant *reply = NULL; alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; reply = g_dbus_proxy_call_finish(func_data->proxy, res, &error); if (!reply) { if (error) { LOGE("dbus error message: %s", error->message); g_error_free(error); return_code = ERR_ALARM_SYSTEM_FAIL; } } else { g_variant_get(reply, "(i)", &return_code); g_variant_unref(reply); LOGD("alarm_set_time_async() dbus success. return_code[%d].", return_code); } if (func_data->callback != NULL) func_data->callback(return_code, func_data->user_data); g_free(func_data); } bool _send_alarm_set_time_async(alarm_context_t context, time_t new_time, alarm_set_time_cb_t result_cb, void *user_data) { alarm_set_time_data_t *func_data; GVariant *param; func_data = g_try_new0(alarm_set_time_data_t, 1); if (func_data == NULL) return false; func_data->callback = result_cb; func_data->user_data = user_data; func_data->proxy = context.proxy; param = g_variant_new("(x)", (gint64)new_time); g_dbus_proxy_call(context.proxy, "alarm_set_time", param, G_DBUS_CALL_FLAGS_NONE, -1, NULL, _alarm_set_time_cb, func_data); return true; } bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, struct timespec new_time, struct timespec req_time, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(xxxx)", (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec, (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec); return_code = __dbus_call_sync(context.proxy, "alarm_set_time_with_propagation_delay", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_set_time_with_propagation_delay dbus sync() success.\ return_code[%d]", return_code); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } static void _alarm_set_time_with_delay_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { int return_code = -1; GError *error = NULL; GVariant *reply = NULL; alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; reply = g_dbus_proxy_call_finish(func_data->proxy, res, &error); if (!reply) { if (error) { LOGE("dbus error message: %s", error->message); g_error_free(error); return_code = ERR_ALARM_SYSTEM_FAIL; } } else { g_variant_get(reply, "(i)", &return_code); g_variant_unref(reply); LOGD("alarm_set_time_with_propagation_delay_async() dbus success.\ return_code[%d].", return_code); } if (func_data->callback != NULL) func_data->callback(return_code, func_data->user_data); g_free(func_data); } bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_data) { alarm_set_time_data_t *func_data; GVariant *param = NULL; func_data = g_try_new0(alarm_set_time_data_t, 1); if (func_data == NULL) return false; func_data->callback = result_cb; func_data->user_data = user_data; func_data->proxy = context.proxy; param = g_variant_new("(xxxx)", (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec, (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec); g_dbus_proxy_call(context.proxy, "alarm_set_time_with_propagation_delay", param, G_DBUS_CALL_FLAGS_NONE, -1, NULL, _alarm_set_time_with_delay_cb, func_data); return true; } bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(s)", tzpath_str); return_code = __dbus_call_sync(context.proxy, "alarm_set_timezone", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_set_timezone dbus sync() success. tz_path[%s] return_code[%d]", tzpath_str, return_code); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_set_global(alarm_context_t context, const alarm_id_t alarm_id, bool global, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(ib)", alarm_id, (gboolean)global); return_code = __dbus_call_sync(context.proxy, "alarm_set_global", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_set_global dbus sync() success. alarm_id[%d], global[%d]\ return_code[%d]", alarm_id, global, return_code); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_get_global(alarm_context_t context, const alarm_id_t alarm_id, bool *global, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; gboolean is_global = FALSE; param = g_variant_new("(i)", alarm_id); return_code = __dbus_call_sync(context.proxy, "alarm_get_global", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(bi)", &is_global, &return_code); *global = is_global ? true : false; LOGD("alarm_get_global dbus sync() success. alarm_id[%d], global[%d]\ return_code[%d]", alarm_id, *global, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; } bool _send_alarm_update(alarm_context_t context, alarm_id_t alarm_id, base_info_t *base_info, int update_flag, int *error_code) { int return_code = -1; GVariant *param = NULL; GVariant *reply = NULL; param = g_variant_new("(iiiiiiiiiixiixi)", alarm_id, base_info->start.year, base_info->start.month, base_info->start.day, base_info->start.hour, base_info->start.min, base_info->start.sec, base_info->end.year, base_info->end.month, base_info->end.day, (gint64)base_info->mode.u_interval.interval, base_info->mode.repeat, base_info->alarm_type, (gint64)base_info->reserved_info, update_flag); return_code = __dbus_call_sync(context.proxy, "alarm_update", param, &reply); if (return_code != ALARMMGR_RESULT_SUCCESS) { if (error_code) *error_code = return_code; return false; } g_variant_get(reply, "(i)", &return_code); LOGD("alarm_update dbus sync() success. alarm_id[%d], return_code[%d]", alarm_id, return_code); if (return_code != 0) { if (error_code) *error_code = return_code; g_variant_unref(reply); return false; } g_variant_unref(reply); return true; }