2 * Copyright (c) 2009-2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <Elementary.h>
18 #include <dbus/dbus-glib.h>
19 #include <dbus/dbus-glib-lowlevel.h>
21 #include "lockscreen.h"
25 #include "lock_time.h"
26 #include "default_lock.h"
28 static struct _s_info {
29 DBusConnection *connection;
30 Eina_List *cbs_list[DBUS_EVENT_MAX];
31 int is_rotate_signal_added;
34 .cbs_list = { NULL, },
35 .is_rotate_signal_added = 0,
39 void (*result_cb)(void *, void *);
43 static void _execute_cbs(int type, void *event_info)
47 Eina_List *list = eina_list_clone(s_info.cbs_list[type]);
48 EINA_LIST_FREE(list, cb) {
50 continue_if(!cb->result_cb);
52 cb->result_cb(cb->result_data, event_info);
56 static void _cbs_fini(void)
60 const Eina_List *l = NULL;
61 const Eina_List *n = NULL;
64 for (i = 0; i < DBUS_EVENT_MAX; i++) {
65 EINA_LIST_FOREACH_SAFE(s_info.cbs_list[i], l, n, cb) {
71 static DBusConnection *_dbus_connection_get(void)
73 if (!s_info.connection) {
75 DBusConnection *connection = NULL;
77 dbus_error_init(&derror);
78 connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &derror);
80 _E("Failed to get dbus connection : %s", derror.message);
81 dbus_error_free(&derror);
84 dbus_connection_setup_with_g_main(connection, NULL);
85 dbus_error_free(&derror);
87 s_info.connection = connection;
90 return s_info.connection;
93 static DBusHandlerResult _dbus_message_recv_cb(DBusConnection *connection, DBusMessage *message, void *data)
95 if (dbus_message_is_signal(message, DBUS_DEVICED_DISPLAY_INTERFACE, DBUS_DEVICED_DISPLAY_MEMBER_LCD_ON)) {
99 const char *state = NULL;
100 dbus_error_init(&derror);
101 ret = dbus_message_get_args(message, &derror, DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID);
103 _E("Failed to get reply (%s:%s)", derror.name, derror.message);
105 _execute_cbs(DBUS_EVENT_LCD_ON, (void*)state);
106 dbus_error_free(&derror);
107 } else if (dbus_message_is_signal(message, DBUS_DEVICED_DISPLAY_INTERFACE, DBUS_DEVICED_DISPLAY_MEMBER_LCD_OFF)) {
111 const char *state = NULL;
112 dbus_error_init(&derror);
113 ret = dbus_message_get_args(message, &derror, DBUS_TYPE_STRING, &state, DBUS_TYPE_INVALID);
115 _E("Failed to get reply (%s:%s)", derror.name, derror.message);
117 _execute_cbs(DBUS_EVENT_LCD_OFF, (void*)state);
118 dbus_error_free(&derror);
119 } else if (dbus_message_is_signal(message, DBUS_ROTATION_INTERFACE, DBUS_ROTATION_MEMBER_CHANGED)) {
123 dbus_error_init(&derror);
124 ret = dbus_message_get_args(message, &derror, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID);
126 _E("Failed to get reply (%s:%s)", derror.name, derror.message);
129 int angle = (state - 1) * 90;
130 angle = (angle < 0) ? 0 : angle;
132 _I("rotation changed : %d", angle);
133 _execute_cbs(DBUS_EVENT_ANGLE_CHANGED, (void*)angle);
134 dbus_error_free(&derror);
137 return DBUS_HANDLER_RESULT_HANDLED;
140 static lock_error_e _dbus_sig_attach(char *path, char *interface, char *member)
143 DBusConnection *connection = NULL;
145 retv_if(!path, LOCK_ERROR_INVALID_PARAMETER);
146 retv_if(!interface, LOCK_ERROR_INVALID_PARAMETER);
147 retv_if(!member, LOCK_ERROR_INVALID_PARAMETER);
150 connection = _dbus_connection_get();
152 _E("Failed to get DBUS connection");
153 return LOCK_ERROR_FAIL;
156 dbus_error_init(&derror);
158 /* Set the DBus rule for the wakeup gesture signal */
159 char rules[512] = { 0, };
160 snprintf(rules, sizeof(rules) - 1, "path='%s',type='signal',interface='%s', member='%s'", path, interface, member);
161 dbus_bus_add_match(connection, rules, &derror);
162 if (dbus_error_is_set(&derror)) {
163 _E("D-BUS rule adding error: %s", derror.message);
164 dbus_error_free(&derror);
165 return LOCK_ERROR_FAIL;
168 /* Set the callback function */
169 if (dbus_connection_add_filter(connection, _dbus_message_recv_cb, NULL, NULL) == FALSE) {
170 _E("Failed to add dbus filter : %s", derror.message);
171 dbus_error_free(&derror);
172 return LOCK_ERROR_FAIL;
175 dbus_error_free(&derror);
177 return LOCK_ERROR_OK;
180 static lock_error_e _dbus_sig_dettach(const char *path, const char *interface, const char *member)
183 DBusConnection *connection = NULL;
185 int ret = LOCK_ERROR_OK;
187 retv_if(!path, LOCK_ERROR_INVALID_PARAMETER);
188 retv_if(!interface, LOCK_ERROR_INVALID_PARAMETER);
189 retv_if(!member, LOCK_ERROR_INVALID_PARAMETER);
191 connection = _dbus_connection_get();
193 _E("failed to get DBUS connection");
194 return LOCK_ERROR_FAIL;
197 dbus_error_init(&err);
198 dbus_connection_remove_filter(connection, _dbus_message_recv_cb, NULL);
200 char rules[512] = { 0, };
202 snprintf(rules, sizeof(rules), "path='%s',type='signal',interface='%s',member='%s'", path, interface, member);
203 dbus_bus_remove_match(connection, rules, &err);
204 if (dbus_error_is_set(&err)) {
205 _E("Failed to dbus_bus_remove_match : %s", err.message);
206 ret = LOCK_ERROR_FAIL;
209 dbus_error_free(&err);
214 int lock_dbus_register_cb(int type, void (*result_cb)(void *, void *), void *result_data)
216 retv_if(!result_cb, LOCK_ERROR_FAIL);
218 dbus_cb_s *cb = calloc(1, sizeof(dbus_cb_s));
219 retv_if(!cb, LOCK_ERROR_FAIL);
221 cb->result_cb = result_cb;
222 cb->result_data = result_data;
224 s_info.cbs_list[type] = eina_list_prepend(s_info.cbs_list[type], cb);
225 retv_if(!s_info.cbs_list[type], LOCK_ERROR_FAIL);
227 return LOCK_ERROR_OK;
230 void lock_dbus_unregister_cb(int type, void (*result_cb)(void *, void *))
235 EINA_LIST_FOREACH_SAFE(s_info.cbs_list[type], l, n, cb) {
237 if (result_cb != cb->result_cb) continue;
238 s_info.cbs_list[type] = eina_list_remove(s_info.cbs_list[type], cb);
244 static void _lcd_on_cb(void *user_data, void *event_info)
250 lockscreen_lcd_off_timer_set();
253 static void _lcd_off_cb(void *user_data, void *event_info)
259 lockscreen_lcd_off_timer_unset();
260 lockscreen_lcd_off_count_reset();
263 void lock_dbus_init(void *data)
265 if (_dbus_sig_attach(DBUS_DEVICED_DISPLAY_PATH,
266 DBUS_DEVICED_DISPLAY_INTERFACE,
267 DBUS_DEVICED_DISPLAY_MEMBER_LCD_ON) != LOCK_ERROR_OK) {
268 _E("Failed to attach LCD on signal filter");
271 if (_dbus_sig_attach(DBUS_DEVICED_DISPLAY_PATH,
272 DBUS_DEVICED_DISPLAY_INTERFACE,
273 DBUS_DEVICED_DISPLAY_MEMBER_LCD_OFF) != LOCK_ERROR_OK) {
274 _E("Failed to attach LCD off signal filter");
277 if (lock_property_rotation_enabled_get()) {
278 if (_dbus_sig_attach(DBUS_ROTATION_PATH,
279 DBUS_ROTATION_INTERFACE,
280 DBUS_ROTATION_MEMBER_CHANGED) != LOCK_ERROR_OK) {
281 _E("Failed to attach rotation signal filter");
285 if (lock_dbus_register_cb(DBUS_EVENT_LCD_ON, _lcd_on_cb, NULL) != LOCK_ERROR_OK) {
286 _E("Failed to register lcd status changed cb");
289 if (lock_dbus_register_cb(DBUS_EVENT_LCD_OFF, _lcd_off_cb, NULL) != LOCK_ERROR_OK) {
290 _E("Failed to register lcd status changed cb");
294 void lock_dbus_fini(void *data)
296 _dbus_sig_dettach(DBUS_DEVICED_DISPLAY_PATH,
297 DBUS_DEVICED_DISPLAY_INTERFACE,
298 DBUS_DEVICED_DISPLAY_MEMBER_LCD_ON);
300 _dbus_sig_dettach(DBUS_DEVICED_DISPLAY_PATH,
301 DBUS_DEVICED_DISPLAY_INTERFACE,
302 DBUS_DEVICED_DISPLAY_MEMBER_LCD_OFF);
304 if (lock_property_rotation_enabled_get()) {
305 _dbus_sig_dettach(DBUS_ROTATION_PATH,
306 DBUS_ROTATION_INTERFACE,
307 DBUS_ROTATION_MEMBER_CHANGED);
310 if (s_info.connection != NULL) {
311 dbus_connection_close(s_info.connection);
312 dbus_connection_unref(s_info.connection);
313 s_info.connection = NULL;
315 _D("DBUS connection is closed");
320 lock_dbus_unregister_cb(DBUS_EVENT_LCD_ON, _lcd_on_cb);
321 lock_dbus_unregister_cb(DBUS_EVENT_LCD_OFF, _lcd_off_cb);