2 * Copyright (c) 2011 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.
32 #define SIGNAL_FLASH_STATE "ChangeFlashState"
34 struct device_cb_info {
39 static dd_list *device_cb_list[DEVICE_CALLBACK_MAX];
40 static int flash_sigid;
42 static void battery_capacity_cb(keynode_t *key, void *data)
44 static device_callback_e type = DEVICE_CALLBACK_BATTERY_CAPACITY;
45 struct device_cb_info *cb_info;
49 val = vconf_keynode_get_int(key);
51 /* invoke the each callback with value */
52 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info)
53 cb_info->cb(type, (void*)val, cb_info->data);
56 static void battery_charging_cb(keynode_t *key, void *data)
58 static device_callback_e type = DEVICE_CALLBACK_BATTERY_CHARGING;
59 struct device_cb_info *cb_info;
63 val = vconf_keynode_get_int(key);
65 /* invoke the each callback with value */
66 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info)
67 cb_info->cb(type, (void*)val, cb_info->data);
70 static void battery_level_cb(keynode_t *key, void *data)
72 static device_callback_e type = DEVICE_CALLBACK_BATTERY_LEVEL;
73 struct device_cb_info *cb_info;
77 val = vconf_keynode_get_int(key);
79 if (val == VCONFKEY_SYSMAN_BAT_LEVEL_EMPTY)
80 status = DEVICE_BATTERY_LEVEL_EMPTY;
81 else if (val == VCONFKEY_SYSMAN_BAT_LEVEL_CRITICAL)
82 status = DEVICE_BATTERY_LEVEL_CRITICAL;
83 else if (val == VCONFKEY_SYSMAN_BAT_LEVEL_LOW)
84 status = DEVICE_BATTERY_LEVEL_LOW;
85 else if (val == VCONFKEY_SYSMAN_BAT_LEVEL_HIGH)
86 status = DEVICE_BATTERY_LEVEL_HIGH;
87 else if (val == VCONFKEY_SYSMAN_BAT_LEVEL_FULL)
88 status = DEVICE_BATTERY_LEVEL_FULL;
92 /* invoke the each callback with value */
93 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info)
94 cb_info->cb(type, (void*)status, cb_info->data);
97 static void display_changed_cb(keynode_t *key, void *data)
99 static device_callback_e type = DEVICE_CALLBACK_DISPLAY_STATE;
100 struct device_cb_info *cb_info;
102 display_state_e state;
105 val = vconf_keynode_get_int(key);
108 case 1: state = DISPLAY_STATE_NORMAL;
110 case 2: state = DISPLAY_STATE_SCREEN_DIM;
112 case 3: state = DISPLAY_STATE_SCREEN_OFF;
118 /* invoke the each callback with value */
119 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info)
120 cb_info->cb(type, (void*)state, cb_info->data);
123 static void flash_state_cb(GDBusConnection *conn,
126 const gchar *interface,
128 GVariant *parameters,
131 static int type = DEVICE_CALLBACK_FLASH_BRIGHTNESS;
132 struct device_cb_info *cb_info;
136 if (strncmp(signal, SIGNAL_FLASH_STATE,
137 sizeof(SIGNAL_FLASH_STATE)) != 0) {
138 _E("wrong parameter : signal(%s)", signal);
142 /* get camera value */
143 g_variant_get(parameters, "(i)", &val);
144 _D("%s - %d", signal, val);
146 /* invoke the each callback with value */
147 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info)
148 cb_info->cb(type, (void*)val, cb_info->data);
151 static int register_signal(const char *bus_name,
152 const char *object_path,
153 const char *interface_name,
155 GDBusSignalCallback callback,
159 GDBusConnection *conn;
162 #if !GLIB_CHECK_VERSION(2,35,0)
166 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
168 _E("fail to get dbus connection : %s", err->message);
173 /* subscribe signal */
174 id = g_dbus_connection_signal_subscribe(conn,
177 signal, /* null to match on all signals */
179 NULL, /* null to match on all kinds of arguments */
180 G_DBUS_SIGNAL_FLAGS_NONE,
185 _E("fail to connect %s signal", signal);
195 static int unregister_signal(int *sig_id)
198 GDBusConnection *conn;
203 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
205 _E("fail to get dbus connection : %s", err->message);
210 /* unsubscribe signal */
211 g_dbus_connection_signal_unsubscribe(conn, *sig_id);
217 static int register_request(device_callback_e type)
220 case DEVICE_CALLBACK_BATTERY_CAPACITY:
221 return vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
222 battery_capacity_cb, NULL);
223 case DEVICE_CALLBACK_BATTERY_LEVEL:
224 return vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS,
225 battery_level_cb, NULL);
226 case DEVICE_CALLBACK_BATTERY_CHARGING:
227 return vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
228 battery_charging_cb, NULL);
229 case DEVICE_CALLBACK_DISPLAY_STATE:
230 return vconf_notify_key_changed(VCONFKEY_PM_STATE,
231 display_changed_cb, NULL);
232 case DEVICE_CALLBACK_FLASH_BRIGHTNESS:
233 /* sig_id begins with 1. */
236 return register_signal(DEVICED_BUS_NAME,
238 DEVICED_INTERFACE_LED,
239 SIGNAL_FLASH_STATE, flash_state_cb, &flash_sigid);
247 static int release_request(device_callback_e type)
250 case DEVICE_CALLBACK_BATTERY_CAPACITY:
251 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
252 battery_capacity_cb);
253 case DEVICE_CALLBACK_BATTERY_LEVEL:
254 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS,
256 case DEVICE_CALLBACK_BATTERY_CHARGING:
257 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
258 battery_charging_cb);
259 case DEVICE_CALLBACK_DISPLAY_STATE:
260 return vconf_ignore_key_changed(VCONFKEY_PM_STATE,
262 case DEVICE_CALLBACK_FLASH_BRIGHTNESS:
265 return unregister_signal(&flash_sigid);
273 int device_add_callback(device_callback_e type, device_changed_cb cb, void *data)
275 struct device_cb_info *cb_info;
279 if (type < 0 || type >= DEVICE_CALLBACK_MAX)
280 return DEVICE_ERROR_INVALID_PARAMETER;
283 return DEVICE_ERROR_INVALID_PARAMETER;
285 /* check if it is the first request */
286 n = DD_LIST_LENGTH(device_cb_list[type]);
288 ret = register_request(type);
290 return DEVICE_ERROR_OPERATION_FAILED;
293 /* check for the same request */
294 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info) {
295 if (cb_info->cb == cb)
296 return DEVICE_ERROR_ALREADY_IN_PROGRESS;
299 /* add device changed callback to list (local) */
300 cb_info = malloc(sizeof(struct device_cb_info));
302 return DEVICE_ERROR_OPERATION_FAILED;
305 cb_info->data = data;
307 DD_LIST_APPEND(device_cb_list[type], cb_info);
309 return DEVICE_ERROR_NONE;
312 int device_remove_callback(device_callback_e type, device_changed_cb cb)
314 struct device_cb_info *cb_info;
318 if (type < 0 || type >= DEVICE_CALLBACK_MAX)
319 return DEVICE_ERROR_INVALID_PARAMETER;
322 return DEVICE_ERROR_INVALID_PARAMETER;
324 /* search for the same element with callback */
325 DD_LIST_FOREACH(device_cb_list[type], elem, cb_info) {
326 if (cb_info->cb == cb)
331 return DEVICE_ERROR_INVALID_PARAMETER;
333 /* remove device callback from list (local) */
334 DD_LIST_REMOVE(device_cb_list[type], cb_info);
337 /* check if this callback is last element */
338 n = DD_LIST_LENGTH(device_cb_list[type]);
340 ret = release_request(type);
342 return DEVICE_ERROR_OPERATION_FAILED;
345 return DEVICE_ERROR_NONE;