Fix build warning based on GCC-9
[platform/core/appfw/alarm-manager.git] / server / alarm-manager-dbus.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17 #include <stdlib.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <sys/socket.h>
21 #include <sys/types.h>
22 #include <sys/un.h>
23
24 #include "alarm.h"
25 #include "alarm-internal.h"
26 #include "alarm-manager-dbus.h"
27 #include "alarm-manager-util.h"
28
29 /*  GDBus Declaration */
30 #define ALARM_MGR_DBUS_PATH     "/org/tizen/alarm/manager"
31 #define ALARM_MGR_DBUS_NAME     "org.tizen.alarm.manager"
32
33 extern __alarm_server_context_t alarm_context;
34 extern GSList *g_expired_alarm_list;
35
36 struct watch_info_t {
37         int watch_id;
38         alarm_id_t alarm_id;
39 };
40
41 static GDBusNodeInfo *introspection_data;
42 static const gchar introspection_xml[] =
43 "<node name='/org/tizen/alarm/manager'>"
44 "  <interface name='org.tizen.alarm.manager'>"
45 "    <method name='alarm_create_periodic'>"
46 "      <arg type='s' name='app_service_name' direction='in' />"
47 "      <arg type='s' name='app_service_name_mod' direction='in' />"
48 "      <arg type='i' name='interval' direction='in' />"
49 "      <arg type='i' name='is_ref' direction='in' />"
50 "      <arg type='i' name='method' direction='in' />"
51 "      <arg type='i' name='alarm_id' direction='out' />"
52 "      <arg type='i' name='return_code' direction='out' />"
53 "    </method>"
54 "    <method name='alarm_create'>"
55 "      <arg type='s' name='app_service_name' direction='in' />"
56 "      <arg type='s' name='app_service_name_mod' direction='in' />"
57 "      <arg type='i' name='alarm_info_start_year' direction='in' />"
58 "      <arg type='i' name='alarm_info_start_month' direction='in' />"
59 "      <arg type='i' name='alarm_info_start_day' direction='in' />"
60 "      <arg type='i' name='alarm_info_start_hour' direction='in' />"
61 "      <arg type='i' name='alarm_info_start_min' direction='in' />"
62 "      <arg type='i' name='alarm_info_start_sec' direction='in' />"
63 "      <arg type='i' name='alarm_info_msec' direction='in' />"
64 "      <arg type='i' name='alarm_info_end_year' direction='in' />"
65 "      <arg type='i' name='alarm_info_end_month' direction='in' />"
66 "      <arg type='i' name='alarm_info_end_day' direction='in' />"
67 "      <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />"
68 "      <arg type='i' name='alarm_info_mode_repeat' direction='in' />"
69 "      <arg type='i' name='alarm_info_alarm_type' direction='in' />"
70 "      <arg type='x' name='alarm_info_reserved_info' direction='in' />"
71 "      <arg type='s' name='alarm_info_reserved_service_name' direction='in' />"
72 "      <arg type='s' name='alarm_info_reserved_service_name_mod' direction='in' />"
73 "      <arg type='i' name='alarm_id' direction='out' />"
74 "      <arg type='i' name='return_code' direction='out' />"
75 "    </method>"
76 "      <method name='alarm_create_appsvc'>"
77 "      <arg type='i' name='alarm_info_start_year' direction='in' />"
78 "      <arg type='i' name='alarm_info_start_month' direction='in' />"
79 "      <arg type='i' name='alarm_info_start_day' direction='in' />"
80 "      <arg type='i' name='alarm_info_start_hour' direction='in' />"
81 "      <arg type='i' name='alarm_info_start_min' direction='in' />"
82 "      <arg type='i' name='alarm_info_start_sec' direction='in' />"
83 "      <arg type='i' name='alarm_info_end_year' direction='in' />"
84 "      <arg type='i' name='alarm_info_end_month' direction='in' />"
85 "      <arg type='i' name='alarm_info_end_day' direction='in' />"
86 "      <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />"
87 "      <arg type='x' name='alarm_info_mode_interval' direction='in' />"
88 "      <arg type='i' name='alarm_info_mode_repeat' direction='in' />"
89 "      <arg type='i' name='alarm_info_alarm_type' direction='in' />"
90 "      <arg type='x' name='alarm_info_reserved_info' direction='in' />"
91 "      <arg type='s' name='alarm_info_bundle_data' direction='in' />"
92 "      <arg type='i' name='alarm_id' direction='out' />"
93 "      <arg type='i' name='return_code' direction='out' />"
94 "    </method>"
95 "      <method name='alarm_create_noti'>"
96 "      <arg type='i' name='alarm_info_start_year' direction='in' />"
97 "      <arg type='i' name='alarm_info_start_month' direction='in' />"
98 "      <arg type='i' name='alarm_info_start_day' direction='in' />"
99 "      <arg type='i' name='alarm_info_start_hour' direction='in' />"
100 "      <arg type='i' name='alarm_info_start_min' direction='in' />"
101 "      <arg type='i' name='alarm_info_start_sec' direction='in' />"
102 "      <arg type='i' name='alarm_info_end_year' direction='in' />"
103 "      <arg type='i' name='alarm_info_end_month' direction='in' />"
104 "      <arg type='i' name='alarm_info_end_day' direction='in' />"
105 "      <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />"
106 "      <arg type='x' name='alarm_info_mode_interval' direction='in' />"
107 "      <arg type='i' name='alarm_info_mode_repeat' direction='in' />"
108 "      <arg type='i' name='alarm_info_alarm_type' direction='in' />"
109 "      <arg type='x' name='alarm_info_reserved_info' direction='in' />"
110 "      <arg type='s' name='alarm_info_noti_data' direction='in' />"
111 "      <arg type='i' name='alarm_id' direction='out' />"
112 "      <arg type='i' name='return_code' direction='out' />"
113 "    </method>"
114 "    <method name='alarm_delete'>"
115 "      <arg type='i' name='alarm_id' direction='in' />"
116 "      <arg type='i' name='alarm_info_return_code' direction='out' />"
117 "    </method>"
118 "    <method name='alarm_delete_all'>"
119 "      <arg type='i' name='alarm_info_return_code' direction='out' />"
120 "    </method>"
121 "    <method name='alarm_update'>"
122 "      <arg type='i' name='alarm_id' direction='in' />"
123 "      <arg type='i' name='alarm_info_start_year' direction='in' />"
124 "      <arg type='i' name='alarm_info_start_month' direction='in' />"
125 "      <arg type='i' name='alarm_info_start_day' direction='in' />"
126 "      <arg type='i' name='alarm_info_start_hour' direction='in' />"
127 "      <arg type='i' name='alarm_info_start_min' direction='in' />"
128 "      <arg type='i' name='alarm_info_start_sec' direction='in' />"
129 "      <arg type='i' name='alarm_info_end_year' direction='in' />"
130 "      <arg type='i' name='alarm_info_end_month' direction='in' />"
131 "      <arg type='i' name='alarm_info_end_day' direction='in' />"
132 "      <arg type='x' name='alarm_info_mode_interval' direction='in' />"
133 "      <arg type='i' name='alarm_info_mode_repeat' direction='in' />"
134 "      <arg type='i' name='alarm_info_alarm_type' direction='in' />"
135 "      <arg type='x' name='alarm_info_reserved_info' direction='in' />"
136 "      <arg type='i' name='update_flag' direction='in' />"
137 "      <arg type='i' name='return_code' direction='out' />"
138 "    </method>"
139 "    <method name='alarm_get_number_of_ids'>"
140 "      <arg type='i' name='number_of_ids' direction='out' />"
141 "      <arg type='i' name='return_code' direction='out' />"
142 "    </method>"
143 "    <method name='alarm_get_list_of_ids'>"
144 "      <arg type='i' name='max_number_of_ids' direction='in' />"
145 "      <arg type='ai' name='alarm_id' direction='out' />"
146 "      <arg type='i' name='number_of_ids' direction='out' />"
147 "      <arg type='i' name='return_code' direction='out' />"
148 "    </method>"
149 "    <method name='alarm_get_appsvc_info'>"
150 "      <arg type='i' name='alarm_id' direction='in' />"
151 "      <arg type='s' name='b_data' direction='out' />"
152 "      <arg type='i' name='return_code' direction='out' />"
153 "    </method>"
154 "    <method name='alarm_get_noti_info'>"
155 "      <arg type='i' name='alarm_id' direction='in' />"
156 "      <arg type='s' name='noti_data' direction='out' />"
157 "      <arg type='i' name='return_code' direction='out' />"
158 "    </method>"
159 "    <method name='alarm_get_info'>"
160 "      <arg type='i' name='alarm_id' direction='in' />"
161 "      <arg type='i' name='alarm_info_start_year' direction='out' />"
162 "      <arg type='i' name='alarm_info_start_month' direction='out' />"
163 "      <arg type='i' name='alarm_info_start_day' direction='out' />"
164 "      <arg type='i' name='alarm_info_start_hour' direction='out' />"
165 "      <arg type='i' name='alarm_info_start_min' direction='out' />"
166 "      <arg type='i' name='alarm_info_start_sec' direction='out' />"
167 "      <arg type='i' name='alarm_info_end_year' direction='out' />"
168 "      <arg type='i' name='alarm_info_end_month' direction='out' />"
169 "      <arg type='i' name='alarm_info_end_day' direction='out' />"
170 "      <arg type='i' name='alarm_info_mode_day_of_week' direction='out' />"
171 "      <arg type='i' name='alarm_info_mode_repeat' direction='out' />"
172 "      <arg type='i' name='alarm_info_alarm_type' direction='out' />"
173 "      <arg type='x' name='alarm_info_reserved_info' direction='out' />"
174 "      <arg type='i' name='return_code' direction='out' />"
175 "    </method>"
176 "      <method name='alarm_set_rtc_time'>"
177 "      <arg type='i' name='alarm_info_year' direction='in' />"
178 "      <arg type='i' name='alarm_info_month' direction='in' />"
179 "      <arg type='i' name='alarm_info_day' direction='in' />"
180 "      <arg type='i' name='alarm_info_hour' direction='in' />"
181 "      <arg type='i' name='alarm_info_min' direction='in' />"
182 "      <arg type='i' name='alarm_info_sec' direction='in' />"
183 "      <arg type='i' name='return_code' direction='out' />"
184 "    </method>"
185 "    <method name='alarm_get_next_duetime'>"
186 "      <arg type='i' name='alarm_id' direction='in' />"
187 "      <arg type='x' name='duetime' direction='out' />"
188 "      <arg type='i' name='return_code' direction='out' />"
189 "    </method>"
190 "    <method name='alarm_get_all_info'>"
191 "      <arg type='s' name='db_path' direction='out' />"
192 "      <arg type='i' name='return_code' direction='out' />"
193 "    </method>"
194 "    <method name='alarm_set_time'>"
195 "      <arg type='x' name='time' direction='in' />"
196 "      <arg type='i' name='return_code' direction='out' />"
197 "    </method>"
198 "    <method name='alarm_set_time_with_propagation_delay'>"
199 "      <arg type='x' name='new_sec' direction='in' />"
200 "      <arg type='x' name='new_nsec' direction='in' />"
201 "      <arg type='x' name='req_sec' direction='in' />"
202 "      <arg type='x' name='req_nsec' direction='in' />"
203 "      <arg type='i' name='return_code' direction='out' />"
204 "    </method>"
205 "    <method name='alarm_set_timezone'>"
206 "      <arg type='s' name='tzpath_str' direction='in' />"
207 "      <arg type='i' name='return_code' direction='out' />"
208 "    </method>"
209 "    <method name='alarm_set_global'>"
210 "      <arg type='i' name='alarm_id' direction='in' />"
211 "      <arg type='b' name='global' direction='in' />"
212 "      <arg type='i' name='return_code' direction='out' />"
213 "    </method>"
214 "    <method name='alarm_get_global'>"
215 "      <arg type='i' name='alarm_id' direction='in' />"
216 "      <arg type='b' name='global' direction='out' />"
217 "      <arg type='i' name='return_code' direction='out' />"
218 "    </method>"
219 "    <signal name='alarm_expired'>"
220 "      <arg type='i' name='alarm_id' />"
221 "      <arg type='s' name='app_service_name' />"
222 "    </signal>"
223 "  </interface>"
224 "</node>";
225
226 static gboolean __send_noti_to_session_bus(char *service_name,
227                 alarm_id_t alarm_id, int msec, uid_t uid)
228 {
229         int fd;
230         int ret;
231         int len;
232         struct sockaddr_un saddr;
233         uint8_t *data;
234         GVariant *gv;
235         uint8_t *gv_data;
236
237         fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
238         if (fd < 0)
239                 return FALSE;
240
241         saddr.sun_family = AF_UNIX;
242         snprintf(saddr.sun_path, sizeof(saddr.sun_path),
243                         "/run/alarm_agent/%d", uid);
244
245         ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
246         if (ret < 0) {
247                 LOGE("connect failed - (errno %d)", errno);
248                 close(fd);
249                 return FALSE;
250         }
251
252         gv = g_variant_new("(iis)", alarm_id, msec, service_name);
253         if (!gv) {
254                 close(fd);
255                 return FALSE;
256         }
257
258         len = g_variant_get_size(gv);
259
260         gv_data = NULL;
261         if (len > 0)
262                 gv_data = (uint8_t *)malloc(len);
263
264         if (!gv_data) {
265                 g_variant_unref(gv);
266                 close(fd);
267                 return FALSE;
268         }
269
270         g_variant_store(gv, gv_data);
271         g_variant_unref(gv);
272
273         data = (uint8_t *)malloc(len + 4);
274         if (!data) {
275                 close(fd);
276                 free(gv_data);
277                 return FALSE;
278         }
279
280         memcpy(data, &len, 4);
281         memcpy(data + 4, gv_data, len);
282         free(gv_data);
283
284         if (send(fd, data, len + 4, 0) == -1) {
285                 LOGE("sendto() failed (errno %d)", errno);
286                 free(data);
287                 close(fd);
288                 return FALSE;
289         }
290
291         free(data);
292         close(fd);
293         return TRUE;
294 }
295
296 static void __on_name_appeared(GDBusConnection *connection,
297                 const gchar     *name,
298                 const gchar     *name_owner,
299                 gpointer         user_data)
300 {
301         SECURE_LOGW("alarm sender name appeared : %s  %s", name, name_owner);
302
303         struct watch_info_t *watch_info = (struct watch_info_t *)user_data;
304         GSList *gs_iter;
305         __alarm_info_t *entry;
306         alarm_id_t alarm_id = watch_info->alarm_id;
307
308         g_bus_unwatch_name(watch_info->watch_id);
309         free(watch_info);
310
311         for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) {
312                 entry = gs_iter->data;
313                 if (alarm_id == entry->alarm_id) {
314                         entry->zombie_mode = false;
315
316                         _alarm_disable_timer(alarm_context);
317                         _clear_scheduled_alarm_list();
318                         _alarm_schedule();
319                         _rtc_set();
320
321                         return;
322                 }
323         }
324 }
325
326 static void __alarm_send_noti_to_application_reply(
327                 GObject *source_object, GAsyncResult *res, gpointer user_data) {
328
329         GVariant *message;
330         GDBusConnection *conn;
331         GError *error = NULL;
332         alarm_id_t *reply_alarm_id = (alarm_id_t *)user_data;
333         char *service_name = "NULL";
334         char *app_unique_name = "NULL";
335         struct watch_info_t *watch_info;
336         char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,};
337
338         GSList *gs_iter;
339         __alarm_info_t *entry;
340         bool is_existed = false;
341
342         conn = G_DBUS_CONNECTION(source_object);
343         message = g_dbus_connection_call_finish(conn, res, &error);
344
345         if (error != NULL && error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) {
346                 for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter) ) {
347                         entry = gs_iter->data;
348
349                         if (*reply_alarm_id == entry->alarm_id) {
350                                 is_existed = true;
351
352                                 app_unique_name =  entry->app_unique_name;
353
354                                 if (entry->dst_service_name == NULL)
355                                         service_name = entry->app_service_name_mod;
356                                 else
357                                         service_name = entry->dst_service_name_mod;
358
359                                 break;
360                         }
361                 }
362
363
364                 LOGW("failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]",
365                                 error->code, error->message, *reply_alarm_id,
366                                 app_unique_name, service_name);
367
368                 snprintf(log_message, sizeof(log_message),
369                                 "failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]",
370                                 error->code, error->message, *reply_alarm_id, app_unique_name, service_name);
371                 _save_module_log("EXPIRED_FAIL", log_message);
372
373                 g_error_free(error);
374
375                 if (is_existed) {
376                         watch_info = (struct watch_info_t *)calloc(1, sizeof(struct watch_info_t));
377                         if (watch_info == NULL) {
378                                 LOGE("Out of memory");
379                                 free(reply_alarm_id);
380                                 return;
381                         }
382
383                         entry->zombie_mode = true;
384
385                         watch_info->alarm_id = entry->alarm_id;
386                         watch_info->watch_id = g_bus_watch_name_on_connection(
387                                         alarm_context.connection,
388                                         service_name,
389                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
390                                         __on_name_appeared,
391                                         NULL,
392                                         watch_info,
393                                         NULL);
394
395                         alarm_context.c_due_time = -1;
396                         _alarm_disable_timer(alarm_context);
397                         _clear_scheduled_alarm_list();
398                         _alarm_schedule();
399                         _rtc_set();
400                 }
401         } else {
402                 g_variant_unref(message);
403         }
404
405         free(reply_alarm_id);
406
407 }
408
409 void _alarm_send_noti_to_application_by_dbus(const char *app_service_name,
410                 alarm_id_t alarm_id, int msec, uid_t uid)
411 {
412         char service_name[MAX_SERVICE_NAME_LEN] = {0,};
413         gboolean ret;
414         alarm_id_t *reply_alarm_id;
415
416         if (app_service_name == NULL || strlen(app_service_name) == 0) {
417                 LOGE("This alarm destination is invalid.");
418                 return;
419         }
420
421         if (_can_skip_expired_cb(alarm_id))
422                 return;
423
424         strncpy(service_name, app_service_name, sizeof(service_name) - 1);
425         SECURE_LOGI("[send expired_alarm(alarm_id=%d) to app_service_name(%s)]",
426                         alarm_id, service_name);
427
428         if (uid >= REGULAR_UID_MIN) {
429                 ret = __send_noti_to_session_bus(service_name, alarm_id, msec, uid);
430                 if (ret != TRUE)
431                         LOGE("failed to send alarm expired noti for %d, %s",
432                                         alarm_id, service_name);
433         } else {
434                 reply_alarm_id = (alarm_id_t *)calloc(1, sizeof(alarm_id_t));
435                 if (reply_alarm_id == NULL) {
436                         LOGE("Out of memory");
437                         return;
438                 }
439
440                 *reply_alarm_id = alarm_id;
441                 g_dbus_connection_call(alarm_context.connection,
442                                 service_name,
443                                 "/org/tizen/alarm/client",
444                                 "org.tizen.alarm.client",
445                                 "alarm_expired",
446                                 g_variant_new("(iis)", alarm_id, msec, service_name),
447                                 NULL,
448                                 G_DBUS_CALL_FLAGS_NONE,
449                                 -1,
450                                 NULL,
451                                 __alarm_send_noti_to_application_reply,
452                                 reply_alarm_id);
453         }
454 }
455
456 static uid_t __get_caller_uid(const char *name)
457 {
458         guint uid;
459         GVariant *ret;
460         GError *error = NULL;
461
462         ret = g_dbus_connection_call_sync(
463                         alarm_context.connection,
464                         "org.freedesktop.DBus",
465                         "/org/freedesktop/DBus",
466                         "org.freedesktop.DBus",
467                         "GetConnectionUnixUser",
468                         g_variant_new("(s)", name),
469                         NULL,
470                         G_DBUS_CALL_FLAGS_NONE,
471                         -1,
472                         NULL,
473                         &error);
474         if (!ret) {
475                 LOGE("failed to get caller uid");
476                 if (error) {
477                         LOGE("dbus error message :  %s", error->message);
478                         g_error_free(error);
479                 }
480                 return -1;
481         }
482         g_variant_get(ret, "(u)", &uid);
483         g_variant_unref(ret);
484
485         return uid;
486 }
487
488 static pid_t __get_caller_pid(const char *name)
489 {
490         guint pid;
491         GVariant *ret;
492         GError *error = NULL;
493
494         ret = g_dbus_connection_call_sync(alarm_context.connection,
495                                         "org.freedesktop.DBus",
496                                         "/org/freedesktop/DBus",
497                                         "org.freedesktop.DBus",
498                                         "GetConnectionUnixProcessID",
499                                         g_variant_new("(s)", name),
500                                         NULL,
501                                         G_DBUS_CALL_FLAGS_NONE,
502                                         -1,
503                                         NULL,
504                                         &error);
505         if (!ret) {
506                 LOGE("failed to get caller pid");
507                 if (error) {
508                         LOGE("dbus error message :  %s", error->message);
509                         g_error_free(error);
510                 }
511                 return -1;
512         }
513         g_variant_get(ret, "(u)", &pid);
514         g_variant_unref(ret);
515
516         return pid;
517 }
518
519 void _display_lock_state(char *state, char *flag, unsigned int timeout)
520 {
521         GDBusMessage *msg = NULL;
522         GDBusMessage *reply = NULL;
523         GVariant *body = NULL;
524         int val = -1;
525
526         LOGD("Lock the display not to enter LCD OFF");
527
528         msg = g_dbus_message_new_method_call(
529                         DEVICED_BUS_NAME,
530                         DEVICED_PATH_DISPLAY,
531                         DEVICED_INTERFACE_DISPLAY,
532                         DEVICED_LOCK_STATE);
533         if (!msg) {
534                 LOGE("g_dbus_message_new_method_call() is failed. (%s:%s-%s)",
535                                 DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_LOCK_STATE);
536                 return;
537         }
538
539         g_dbus_message_set_body(
540                         msg, g_variant_new("(sssi)", state, flag, "NULL", timeout));
541
542         reply = g_dbus_connection_send_message_with_reply_sync(
543                         alarm_context.connection,
544                         msg,
545                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
546                         DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL);
547         if (!reply) {
548                 LOGE("No reply.\
549                                 g_dbus_connection_send_message_with_reply_sync() is failed.");
550         } else {
551                 body = g_dbus_message_get_body(reply);
552                 if (!body) {
553                         LOGE("g_dbus_message_get_body() is failed.");
554                 } else {
555                         g_variant_get(body, "(i)", &val);
556                         if (val != 0) {
557                                 LOGE("Failed to lock display");
558                         } else {
559                                 LOGD("Lock LCD OFF is successfully done");
560                         }
561                 }
562         }
563
564         g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL);
565         g_object_unref(msg);
566         if (reply)
567                 g_object_unref(reply);
568 }
569
570 void _display_unlock_state(char *state, char *flag)
571 {
572         GDBusMessage *msg = NULL;
573         GDBusMessage *reply = NULL;
574         GVariant *body = NULL;
575         int val = -1;
576
577         LOGD("Unlock the display from LCD OFF");
578
579         msg = g_dbus_message_new_method_call(
580                         DEVICED_BUS_NAME,
581                         DEVICED_PATH_DISPLAY,
582                         DEVICED_INTERFACE_DISPLAY,
583                         DEVICED_UNLOCK_STATE);
584         if (!msg) {
585                 LOGE("g_dbus_message_new_method_call() is failed. (%s:%s-%s)",
586                                 DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_UNLOCK_STATE);
587                 return;
588         }
589
590         g_dbus_message_set_body(msg, g_variant_new("(ss)", state, flag));
591
592         reply = g_dbus_connection_send_message_with_reply_sync(
593                         alarm_context.connection,
594                         msg,
595                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
596                         DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL);
597         if (!reply) {
598                 LOGE("No reply.\
599                                 g_dbus_connection_send_message_with_reply_sync() is failed.");
600         } else {
601                 body = g_dbus_message_get_body(reply);
602                 if (!body) {
603                         LOGE("g_dbus_message_get_body() is failed.");
604                 } else {
605                         g_variant_get(body, "(i)", &val);
606                         if (val != 0) {
607                                 LOGE("Failed to unlock display");
608                         } else {
609                                 LOGD("Unlock LCD OFF is successfully done");
610                         }
611                 }
612         }
613
614         g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL);
615         g_object_unref(msg);
616         if (reply)
617                 g_object_unref(reply);
618 }
619
620 static void handle_method_call(GDBusConnection *connection,
621         const gchar *sender, const gchar *object_path,
622         const gchar *interface_name, const gchar *method_name,
623         GVariant *parameters, GDBusMethodInvocation *invoc,
624         gpointer user_data)
625 {
626         int ret = ALARMMGR_RESULT_SUCCESS;
627         int num_of_alarm = 0;
628         int alarm_id = 0;
629         const char *name = g_dbus_method_invocation_get_sender(invoc);
630         uid_t uid = __get_caller_uid(name);
631         pid_t pid = __get_caller_pid(name);
632
633         if (g_strcmp0(method_name, "alarm_create_periodic") == 0) {
634                 ret = alarm_manager_alarm_create_periodic(parameters, uid, pid, &alarm_id);
635                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret));
636         } else if (g_strcmp0(method_name, "alarm_create") == 0) {
637                 ret = alarm_manager_alarm_create(parameters, uid, pid, &alarm_id);
638                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret));
639         } else if (g_strcmp0(method_name, "alarm_create_appsvc") == 0) {
640                 ret = alarm_manager_alarm_create_appsvc(parameters, uid, pid, &alarm_id);
641                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret));
642         } else if (g_strcmp0(method_name, "alarm_create_noti") == 0) {
643                 const char *notification_priv = "http://tizen.org/privilege/notification";
644                 ret = _cynara_check(invoc, notification_priv, pid);
645                 if (ret == ALARMMGR_RESULT_SUCCESS) {
646                         ret = alarm_manager_alarm_create_noti(parameters, uid, pid, &alarm_id);
647                 }
648                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret));
649         } else if (g_strcmp0(method_name, "alarm_delete") == 0) {
650                 ret = alarm_manager_alarm_delete(parameters, uid, pid);
651                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
652         } else if (g_strcmp0(method_name, "alarm_delete_all") == 0) {
653                 ret = alarm_manager_alarm_delete_all(parameters, uid, pid);
654                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
655         } else if (g_strcmp0(method_name, "alarm_update") == 0) {
656                 ret = alarm_manager_alarm_update(parameters, uid, pid);
657                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
658         } else if (g_strcmp0(method_name, "alarm_get_number_of_ids") == 0) {
659                 ret = alarm_manager_alarm_get_number_of_ids(uid, pid, &num_of_alarm);
660                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_alarm, ret));
661         } else if (g_strcmp0(method_name, "alarm_get_list_of_ids") == 0) {
662                 GVariant *arr = NULL;
663
664                 ret = alarm_manager_alarm_get_list_of_ids(parameters, uid, pid, &arr, &num_of_alarm);
665                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", arr, num_of_alarm, ret));
666         } else if (g_strcmp0(method_name, "alarm_get_appsvc_info") == 0) {
667                 gchar *b_data = NULL;
668
669                 ret = alarm_manager_alarm_get_appsvc_info(parameters, uid, &b_data);
670                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", b_data, ret));
671                 if (b_data)
672                         free(b_data);
673         } else if (g_strcmp0(method_name, "alarm_get_noti_info") == 0) {
674                 gchar *noti_data = NULL;
675
676                 ret = alarm_manager_alarm_get_noti_info(parameters, uid, &noti_data);
677                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", noti_data, ret));
678
679                 if (noti_data)
680                         free(noti_data);
681         } else if (g_strcmp0(method_name, "alarm_get_info") == 0) {
682                 alarm_info_t alarm_info = { 0, };
683
684                 ret = alarm_manager_alarm_get_info(parameters, uid, &alarm_info);
685
686                 g_dbus_method_invocation_return_value(
687                                 invoc, g_variant_new("(iiiiiiiiiiiixi)",
688                                         alarm_info.start.year, alarm_info.start.month,
689                                         alarm_info.start.day, alarm_info.start.hour,
690                                         alarm_info.start.min, alarm_info.start.sec,
691                                         alarm_info.end.year, alarm_info.end.month,
692                                         alarm_info.end.day, alarm_info.mode.u_interval.day_of_week,
693                                         alarm_info.mode.repeat, alarm_info.alarm_type,
694                                         (gint64)alarm_info.reserved_info, ret));
695         } else if (g_strcmp0(method_name, "alarm_get_next_duetime") == 0) {
696                 time_t duetime;
697                 ret = alarm_manager_alarm_get_next_duetime(parameters, uid, &duetime);
698
699                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(xi)", (gint64)duetime, ret));
700         } else if (g_strcmp0(method_name, "alarm_get_all_info") == 0) {
701                 char *db_path = NULL;
702
703                 ret = alarm_manager_alarm_get_all_info(uid, &db_path);
704                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", db_path, ret));
705
706                 if (db_path)
707                         free(db_path);
708         } else if (g_strcmp0(method_name, "alarm_set_rtc_time") == 0) {
709                 _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0);
710                 ret = alarm_manager_alarm_set_rtc_time(parameters);
711                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
712                 _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN);
713         } else if (g_strcmp0(method_name, "alarm_set_time") == 0) {
714                 _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0);
715                 ret = alarm_manager_alarm_set_time(parameters, pid);
716                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
717                 _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN);
718         } else if (g_strcmp0(method_name, "alarm_set_time_with_propagation_delay") == 0) {
719                 _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0);
720                 ret = alarm_manager_alarm_set_time_with_propagation_delay(parameters, pid);
721                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
722                 _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN);
723         } else if (g_strcmp0(method_name, "alarm_set_timezone") == 0) {
724                 _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0);
725                 ret = alarm_manager_alarm_set_timezone(parameters);
726                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
727                 _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN);
728         } else if (g_strcmp0(method_name, "alarm_set_global") == 0) {
729                 ret = alarm_manager_alarm_set_global(parameters, uid);
730                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret));
731         } else if (g_strcmp0(method_name, "alarm_get_global") == 0) {
732                 gboolean global;
733
734                 ret = alarm_manager_alarm_get_global(parameters, &global);
735                 g_dbus_method_invocation_return_value(invoc, g_variant_new("(bi)", global, ret));
736         }
737 }
738
739 static const GDBusInterfaceVTable interface_vtable = {
740         handle_method_call,
741         NULL,
742         NULL
743 };
744
745 static void __on_bus_name_acquired(GDBusConnection  *connection,
746                                 const gchar *name,
747                                 gpointer user_data)
748 {
749         LOGD("bus acquired(%s)", name);
750
751         guint reg_id = 0;
752         GError *error = NULL;
753
754         reg_id = g_dbus_connection_register_object(connection,
755                 ALARM_MGR_DBUS_PATH,
756                 introspection_data->interfaces[0],
757                 &interface_vtable,
758                 NULL, NULL, &error);
759         if (reg_id == 0) {
760                 LOGE("g_dbus_connection_register_object error(%s)", error->message);
761                 g_error_free(error);
762         }
763 }
764
765 static void __on_bus_name_owner_changed(GDBusConnection  *connection,
766                                 const gchar *sender_name,
767                                 const gchar *object_path,
768                                 const gchar *interface_name,
769                                 const gchar *signal_name,
770                                 GVariant *parameters,
771                                 gpointer user_data)
772 {
773         GSList *entry = NULL;
774         __expired_alarm_t *expire_info = NULL;
775         char *service_name = NULL;
776
777         /* On expiry, the killed app can be launched by aul. Then, the owner of the bus name which was registered by the app is changed.
778          * In this case, "NameOwnerChange" signal is broadcasted. */
779         if (signal_name && strcmp(signal_name, "NameOwnerChanged") == 0) {
780                 g_variant_get(parameters, "(&sss)", &service_name, NULL, NULL);
781
782                 for (entry = g_expired_alarm_list; entry; entry = entry->next) {
783                         if (entry->data) {
784                                 expire_info = (__expired_alarm_t *) entry->data;
785                                 SECURE_LOGD("expired service(%s), owner changed service(%s)",
786                                                 expire_info->service_name, service_name);
787
788                                 if (strcmp(expire_info->service_name, service_name) == 0) {
789                                         SECURE_LOGE("expired service name(%s) alarm_id (%d)",
790                                                         expire_info->service_name, expire_info->alarm_id);
791                                         _alarm_send_noti_to_application_by_dbus(
792                                                         expire_info->service_name,
793                                                         expire_info->alarm_id,
794                                                         0,
795                                                         expire_info->uid);
796                                         g_expired_alarm_list =
797                                                 g_slist_remove(g_expired_alarm_list, entry->data);
798                                         g_free(expire_info);
799                                 }
800                         }
801                 }
802         }
803 }
804
805 bool _initialize_dbus(void)
806 {
807         GDBusConnection *connection = NULL;
808         GError *error = NULL;
809         guint subsc_id;
810         guint owner_id;
811         LOGD("__initialize_dbus Enter");
812
813         connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
814         if (connection == NULL) {
815                 LOGE("g_bus_get_sync() is failed");
816                 if (error) {
817                         LOGE("dbus error message : %s", error->message);
818                         g_error_free(error);
819                 }
820                 return false;
821         }
822
823         subsc_id = g_dbus_connection_signal_subscribe(connection,
824                         "org.freedesktop.DBus", "org.freedesktop.DBus",
825                         "NameOwnerChanged", "/org/freedesktop/DBus", NULL,
826                         G_DBUS_SIGNAL_FLAGS_NONE, __on_bus_name_owner_changed, NULL, NULL);
827         if (subsc_id == 0) {
828                 LOGE("Subscribing to signal for invoking callback is failed.");
829                 g_object_unref(connection);
830                 return false;
831         }
832
833         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
834         if (!introspection_data) {
835                 LOGE("g_dbus_node_info_new_for_xml error(%s)", error->message);
836                 g_object_unref(connection);
837                 g_error_free(error);
838                 return false;
839         }
840
841         owner_id = g_bus_own_name_on_connection(connection,
842                         ALARM_MGR_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE,
843                         __on_bus_name_acquired, NULL, NULL, NULL);
844
845         if (owner_id == 0) {
846                 LOGE("Acquiring the own name is failed.");
847                 g_dbus_node_info_unref(introspection_data);
848                 g_object_unref(connection);
849                 return false;
850         }
851
852         alarm_context.connection = connection;
853
854         return true;
855 }