tizen 2.3.1 release
[framework/api/runtime-info.git] / src / runtime_info.c
1 /*
2  * Copyright (c) 2011 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
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <vconf.h>
22 #include <dlog.h>
23
24 #include <runtime_info.h>
25 #include <runtime_info_private.h>
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30
31 #define LOG_TAG "CAPI_SYSTEM_RUNTIME_INFO"
32
33 #define RUNTIME_INFO_MAX -1
34
35 typedef struct {
36         runtime_info_changed_cb changed_cb;
37         void *user_data;
38         runtime_info_value_h most_recent_value;
39 } runtime_info_event_subscription_s;
40
41 typedef runtime_info_event_subscription_s * runtime_info_event_subscription_h;
42
43 typedef struct {
44         runtime_info_key_e key;
45         runtime_info_data_type_e data_type;
46         runtime_info_func_get_value get_value;
47         runtime_info_func_set_event_cb set_event_cb;
48         runtime_info_func_unset_event_cb unset_event_cb;
49         runtime_info_event_subscription_h event_subscription;
50 } runtime_info_item_s;
51
52 typedef runtime_info_item_s * runtime_info_item_h;
53
54 runtime_info_item_s runtime_info_item_table[] = {
55
56 {
57         RUNTIME_INFO_KEY_FLIGHT_MODE_ENABLED, /**<Indicates whether the device is in flight mode. */
58         RUNTIME_INFO_DATA_TYPE_BOOL,
59         runtime_info_flightmode_get_value,
60         runtime_info_flightmode_set_event_cb,
61         runtime_info_flightmode_unset_event_cb,
62         NULL
63 },
64
65
66 {
67         RUNTIME_INFO_KEY_WIFI_STATUS, /**<Indicates the current status of Wi-Fi. */
68         RUNTIME_INFO_DATA_TYPE_INT,
69         runtime_info_wifi_status_get_value,
70         runtime_info_wifi_status_set_event_cb,
71         runtime_info_wifi_status_unset_event_cb,
72         NULL
73 },
74
75
76 {
77         RUNTIME_INFO_KEY_BLUETOOTH_ENABLED, /**<Indicates whether Bluetooth is enabled. */
78         RUNTIME_INFO_DATA_TYPE_BOOL,
79         runtime_info_bt_enabled_get_value,
80         runtime_info_bt_enabled_set_event_cb,
81         runtime_info_bt_enabled_unset_event_cb,
82         NULL
83 },
84
85 {
86         RUNTIME_INFO_KEY_WIFI_HOTSPOT_ENABLED, /**<Indicates whether Wi-Fi hotspot is enabled. */
87         RUNTIME_INFO_DATA_TYPE_BOOL,
88         runtime_info_wifi_hotspot_get_value,
89         runtime_info_wifi_hotspot_set_event_cb,
90         runtime_info_wifi_hotspot_unset_event_cb,
91         NULL
92 },
93
94 {
95         RUNTIME_INFO_KEY_BLUETOOTH_TETHERING_ENABLED, /**<Indicates whether Bluetooth tethering is enabled. */
96         RUNTIME_INFO_DATA_TYPE_BOOL,
97         runtime_info_bt_hotspot_get_value,
98         runtime_info_bt_hotspot_set_event_cb,
99         runtime_info_bt_hotspot_unset_event_cb,
100         NULL
101 },
102
103 {
104         RUNTIME_INFO_KEY_USB_TETHERING_ENABLED, /**<Indicates whether USB tethering is enabled. */
105         RUNTIME_INFO_DATA_TYPE_BOOL,
106         runtime_info_usb_hotspot_get_value,
107         runtime_info_usb_hotspot_set_event_cb,
108         runtime_info_usb_hotspot_unset_event_cb,
109         NULL
110 },
111
112 {
113         RUNTIME_INFO_KEY_LOCATION_SERVICE_ENABLED, /**<Indicates whether the location service is allowed to use location data from GPS satellites. */
114         RUNTIME_INFO_DATA_TYPE_BOOL,
115         runtime_info_location_service_get_value,
116         runtime_info_location_service_set_event_cb,
117         runtime_info_location_service_unset_event_cb,
118         NULL
119 },
120
121 {
122         RUNTIME_INFO_KEY_LOCATION_ADVANCED_GPS_ENABLED, /**<Indicates whether the location service is allowed to download location data for GPS operation. */
123         RUNTIME_INFO_DATA_TYPE_BOOL,
124         runtime_info_location_agps_get_value,
125         runtime_info_location_agps_set_event_cb,
126         runtime_info_location_agps_unset_event_cb,
127         NULL
128 },
129
130 {
131         RUNTIME_INFO_KEY_LOCATION_NETWORK_POSITION_ENABLED, /**<Indicates whether the location service is allowed to use location data from cellular and Wi-Fi. */
132         RUNTIME_INFO_DATA_TYPE_BOOL,
133         runtime_info_location_network_get_value,
134         runtime_info_location_network_set_event_cb,
135         runtime_info_location_network_unset_event_cb,
136         NULL
137 },
138
139 {
140         RUNTIME_INFO_KEY_PACKET_DATA_ENABLED, /**<Indicates Whether the packet data through 3G network is enabled. */
141         RUNTIME_INFO_DATA_TYPE_BOOL,
142         runtime_info_packet_data_get_value,
143         runtime_info_packet_data_set_event_cb,
144         runtime_info_packet_data_unset_event_cb,
145         NULL
146 },
147
148 {
149         RUNTIME_INFO_KEY_DATA_ROAMING_ENABLED, /**<Indicates whether data roaming is enabled. */
150         RUNTIME_INFO_DATA_TYPE_BOOL,
151         runtime_info_data_roaming_get_value,
152         runtime_info_data_roaming_set_event_cb,
153         runtime_info_data_roaming_unset_event_cb,
154         NULL
155 },
156
157 {
158         RUNTIME_INFO_KEY_SILENT_MODE_ENABLED, /**<Indicates whether the device is in silent mode. */
159         RUNTIME_INFO_DATA_TYPE_BOOL,
160         runtime_info_silent_mode_get_value,
161         runtime_info_silent_mode_set_event_cb,
162         runtime_info_silent_mode_unset_event_cb,
163         NULL
164 },
165
166 {
167         RUNTIME_INFO_KEY_VIBRATION_ENABLED, /**<Indicates whether vibration is enabled. */
168         RUNTIME_INFO_DATA_TYPE_BOOL,
169         runtime_info_vibration_enabled_get_value,
170         runtime_info_vibration_enabled_set_event_cb,
171         runtime_info_vibration_enabled_unset_event_cb,
172         NULL
173 },
174
175 {
176         RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, /**<Indicates the current time format. */
177         RUNTIME_INFO_DATA_TYPE_BOOL,
178         runtime_info_24hour_format_get_value,
179         runtime_info_24hour_format_set_event_cb,
180         runtime_info_24hour_format_unset_event_cb,
181         NULL
182 },
183
184 {
185         RUNTIME_INFO_KEY_FIRST_DAY_OF_WEEK, /**<Indicates the first day of week. */
186         RUNTIME_INFO_DATA_TYPE_INT,
187         runtime_info_first_day_of_week_get_value,
188         runtime_info_first_day_of_week_set_event_cb,
189         runtime_info_first_day_of_week_unset_event_cb,
190         NULL
191 },
192
193 {
194         RUNTIME_INFO_KEY_LANGUAGE, /**<Indicates the current language setting. */
195         RUNTIME_INFO_DATA_TYPE_STRING,
196         runtime_info_language_get_value,
197         runtime_info_language_set_event_cb,
198         runtime_info_language_unset_event_cb,
199         NULL
200 },
201
202 {
203         RUNTIME_INFO_KEY_REGION, /**<Indicates the current region setting. */
204         RUNTIME_INFO_DATA_TYPE_STRING,
205         runtime_info_region_get_value,
206         runtime_info_region_set_event_cb,
207         runtime_info_region_unset_event_cb,
208         NULL
209 },
210
211 {
212         RUNTIME_INFO_KEY_AUDIO_JACK_CONNECTED, /**<Indicates whether audio jack is connected. */
213         RUNTIME_INFO_DATA_TYPE_BOOL,
214         runtime_info_audiojack_get_value,
215         runtime_info_audiojack_set_event_cb,
216         runtime_info_audiojack_unset_event_cb,
217         NULL
218 },
219
220 {
221         RUNTIME_INFO_KEY_GPS_STATUS, /**<Indicates the current status of GPS. */
222         RUNTIME_INFO_DATA_TYPE_INT,
223         runtime_info_gps_status_get_value,
224         runtime_info_gps_status_set_event_cb,
225         runtime_info_gps_status_unset_event_cb,
226         NULL
227 },
228
229 {
230         RUNTIME_INFO_KEY_BATTERY_IS_CHARGING, /**<Indicates the battery is currently charging. */
231         RUNTIME_INFO_DATA_TYPE_BOOL,
232         runtime_info_battery_charging_get_value,
233         runtime_info_battery_charging_set_event_cb,
234         runtime_info_battery_charging_unset_event_cb,
235         NULL
236 },
237
238 {
239         RUNTIME_INFO_KEY_TV_OUT_CONNECTED, /**<Indicates whether TV out is connected. */
240         RUNTIME_INFO_DATA_TYPE_BOOL,
241         runtime_info_tvout_connected_get_value,
242         runtime_info_tvout_connected_set_event_cb,
243         runtime_info_tvout_connected_unset_event_cb,
244         NULL
245 },
246
247 {
248         RUNTIME_INFO_KEY_AUDIO_JACK_STATUS, /**<Indicates the current status of audio jack. */
249         RUNTIME_INFO_DATA_TYPE_INT,
250         runtime_info_audio_jack_status_get_value,
251         runtime_info_audio_jack_status_set_event_cb,
252         runtime_info_audio_jack_status_unset_event_cb,
253         NULL
254 },
255
256 {
257         RUNTIME_INFO_KEY_SLIDING_KEYBOARD_OPENED, /**<Indicates whether sliding keyboard is opened. */
258         RUNTIME_INFO_DATA_TYPE_BOOL,
259         runtime_info_sliding_keyboard_opened_get_value,
260         runtime_info_sliding_keyboard_opened_set_event_cb,
261         runtime_info_sliding_keyboard_opened_unset_event_cb,
262         NULL
263 },
264
265 {
266         RUNTIME_INFO_KEY_USB_CONNECTED, /**<Indicates whether usb is connected. */
267         RUNTIME_INFO_DATA_TYPE_BOOL,
268         runtime_info_usb_connected_get_value,
269         runtime_info_usb_connected_set_event_cb,
270         runtime_info_usb_connected_unset_event_cb,
271         NULL
272 },
273
274 {
275         RUNTIME_INFO_KEY_CHARGER_CONNECTED, /**<Indicates whether charger is connected. */
276         RUNTIME_INFO_DATA_TYPE_BOOL,
277         runtime_info_charger_connected_get_value,
278         runtime_info_charger_connected_set_event_cb,
279         runtime_info_charger_connected_unset_event_cb,
280         NULL
281 },
282
283 {
284         RUNTIME_INFO_KEY_VIBRATION_LEVEL_HAPTIC_FEEDBACK, /**<Indicates the current vibration level of haptic feedback. */
285         RUNTIME_INFO_DATA_TYPE_INT,
286         runtime_info_vibration_level_haptic_feedback_get_value,
287         runtime_info_vibration_level_haptic_feedback_set_event_cb,
288         runtime_info_vibration_level_haptic_feedback_unset_event_cb,
289         NULL
290 },
291
292 {
293         RUNTIME_INFO_KEY_AUTO_ROTATION_ENABLED, /**<Indicates whether auto rotation is enabled. */
294         RUNTIME_INFO_DATA_TYPE_BOOL,
295         runtime_info_auto_rotation_enabled_get_value,
296         runtime_info_auto_rotation_enabled_set_event_cb,
297         runtime_info_auto_rotation_enabled_unset_event_cb,
298         NULL
299 },
300
301 {
302         RUNTIME_INFO_MAX, RUNTIME_INFO_DATA_TYPE_INT, NULL, NULL, NULL, NULL
303 }
304
305 };
306
307 static int runtime_info_get_item(runtime_info_key_e key, runtime_info_item_h *runtime_info_item)
308 {
309         int index = 0;
310
311         while (runtime_info_item_table[index].key != RUNTIME_INFO_MAX) {
312                 if (runtime_info_item_table[index].key == key) {
313                         *runtime_info_item = &runtime_info_item_table[index];
314                         return 0;
315                 }
316
317                 index++;
318         }
319
320         return -1;
321 }
322
323 int runtime_info_get_value(runtime_info_key_e key, runtime_info_data_type_e data_type, runtime_info_value_h value)
324 {
325         runtime_info_item_h runtime_info_item;
326         runtime_info_func_get_value get_value;
327         int ret;
328
329         if (runtime_info_get_item(key, &runtime_info_item))     {
330                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
331                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
332         }
333
334         if (runtime_info_item->data_type != data_type) {
335                 LOGE("INVALID_PARAMETER(0x%08x) : invalid data type", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
336                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
337         }
338
339         get_value = runtime_info_item->get_value;
340
341         if (get_value == NULL) {
342                 LOGE("IO_ERROR(0x%08x) : failed to call getter for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
343                 return RUNTIME_INFO_ERROR_IO_ERROR;
344         }
345
346         ret = get_value(value);
347         if (ret != RUNTIME_INFO_ERROR_NONE)
348                 LOGE("IO_ERROR(0x%08x) : failed to get the runtime informaion / key(%d)", ret, key);
349
350         return ret;
351 }
352
353 API int runtime_info_get_value_int(runtime_info_key_e key, int *value)
354 {
355         int retcode;
356         runtime_info_value_u runtime_info_value;
357
358         if (value == NULL) {
359                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
360                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
361         }
362
363         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_INT, &runtime_info_value);
364
365         if (retcode == RUNTIME_INFO_ERROR_NONE)
366                 *value = runtime_info_value.i;
367
368         return retcode;
369 }
370
371 API int runtime_info_get_value_bool(runtime_info_key_e key, bool *value)
372 {
373         int retcode;
374         runtime_info_value_u runtime_info_value;
375
376         if (value == NULL) {
377                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
378                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
379         }
380
381         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_BOOL, &runtime_info_value);
382
383         if (retcode == RUNTIME_INFO_ERROR_NONE)
384                 *value = runtime_info_value.b;
385
386         return retcode;
387 }
388
389 API int runtime_info_get_value_double(runtime_info_key_e key, double *value)
390 {
391         int retcode;
392         runtime_info_value_u runtime_info_value;
393
394         if (value == NULL) {
395                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
396                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
397         }
398
399         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_DOUBLE, &runtime_info_value);
400
401         if (retcode == RUNTIME_INFO_ERROR_NONE)
402                 *value = runtime_info_value.d;
403
404         return retcode;
405 }
406
407 API int runtime_info_get_value_string(runtime_info_key_e key, char **value)
408 {
409         int retcode;
410         runtime_info_value_u runtime_info_value;
411
412         if (value == NULL) {
413                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
414                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
415         }
416
417         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_STRING, &runtime_info_value);
418
419         if (retcode == RUNTIME_INFO_ERROR_NONE)
420                 *value = runtime_info_value.s;
421
422         return retcode;
423 }
424
425 API int runtime_info_set_changed_cb(runtime_info_key_e key, runtime_info_changed_cb callback, void *user_data)
426 {
427         runtime_info_item_h runtime_info_item;
428         runtime_info_func_set_event_cb set_event_cb;
429         bool subscribe_event = false;
430         runtime_info_value_u val;
431         int ret;
432
433         if (callback == NULL) {
434                 LOGE("INVALID_PARAMETER(0x%08x)", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
435                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
436         }
437
438         if (runtime_info_get_item(key, &runtime_info_item))     {
439                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
440                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
441         }
442
443         set_event_cb = runtime_info_item->set_event_cb;
444
445         if (set_event_cb == NULL) {
446                 LOGE("IO_ERROR(0x%08x) : failed to set callback for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
447                 return RUNTIME_INFO_ERROR_IO_ERROR;
448         }
449
450         ret = runtime_info_item->get_value(&val);
451         if (ret != RUNTIME_INFO_ERROR_NONE) {
452                 LOGE("The key (%d) %s(%d)", key, ret == RUNTIME_INFO_ERROR_NOT_SUPPORTED ? "is not supported" : "has error", ret);
453                 return ret;
454         }
455
456         if (runtime_info_item->event_subscription == NULL) {
457                 subscribe_event = true;
458
459                 runtime_info_event_subscription_h event_subscription;
460                 event_subscription = malloc(sizeof(runtime_info_event_subscription_s));
461
462                 if (event_subscription == NULL) {
463                         LOGE("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
464                         return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
465                 }
466
467                 runtime_info_item->event_subscription = event_subscription;
468                 runtime_info_item->event_subscription->most_recent_value = NULL;
469         }
470
471         runtime_info_item->event_subscription->changed_cb = callback;
472         runtime_info_item->event_subscription->user_data = user_data;
473
474         if (runtime_info_item->event_subscription->most_recent_value != NULL)
475                 free(runtime_info_item->event_subscription->most_recent_value);
476
477         runtime_info_item->event_subscription->most_recent_value = NULL;
478
479         if (subscribe_event == true)
480                 return set_event_cb();
481         else
482                 return RUNTIME_INFO_ERROR_NONE;
483 }
484
485 API int runtime_info_unset_changed_cb(runtime_info_key_e key)
486 {
487         runtime_info_item_h runtime_info_item;
488         runtime_info_func_unset_event_cb unset_event_cb;
489         runtime_info_value_u val;
490         int ret;
491
492         if (runtime_info_get_item(key, &runtime_info_item))     {
493                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
494                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
495         }
496
497         ret = runtime_info_item->get_value(&val);
498         if (ret != RUNTIME_INFO_ERROR_NONE) {
499                 LOGE("The key (%d) %s(%d)", key, ret == RUNTIME_INFO_ERROR_NOT_SUPPORTED ? "is not supported" : "has error", ret);
500                 return ret;
501         }
502
503         if (runtime_info_item->event_subscription != NULL) {
504                 if (runtime_info_item->event_subscription->most_recent_value != NULL) {
505                         free(runtime_info_item->event_subscription->most_recent_value);
506                         runtime_info_item->event_subscription->most_recent_value = NULL;
507                 }
508
509                 free(runtime_info_item->event_subscription);
510                 runtime_info_item->event_subscription = NULL;
511         }
512
513         unset_event_cb = runtime_info_item->unset_event_cb;
514
515         if (unset_event_cb == NULL)     {
516                 LOGE("IO_ERROR(0x%08x) : failed to unset callback for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
517                 return RUNTIME_INFO_ERROR_IO_ERROR;
518         }
519
520         unset_event_cb();
521
522         return RUNTIME_INFO_ERROR_NONE;
523 }
524
525 void runtime_info_updated(runtime_info_key_e key)
526 {
527         runtime_info_item_h runtime_info_item;
528         runtime_info_value_u current_value;
529         bool dispatch_event = true;
530         int retcode;
531
532         if (runtime_info_get_item(key, &runtime_info_item))     {
533                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
534                 return;
535         }
536
537         if (runtime_info_item->event_subscription == NULL) {
538                 LOGE("IO_ERROR(0x%08x) : invalid event subscription", RUNTIME_INFO_ERROR_IO_ERROR);
539                 return;
540         }
541
542         memset(&current_value, 0, sizeof(runtime_info_value_u));
543
544         retcode = runtime_info_get_value(key, runtime_info_item->data_type, &current_value);
545
546         if (retcode != RUNTIME_INFO_ERROR_NONE) {
547                 LOGE("IO_ERROR(0x%08x) : failed to get the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
548                 return;
549         }
550
551         if (runtime_info_item->event_subscription->most_recent_value != NULL) {
552                 if (!memcmp(runtime_info_item->event_subscription->most_recent_value, &current_value, sizeof(runtime_info_value_u)))
553                         dispatch_event = false;
554         } else {
555                 runtime_info_item->event_subscription->most_recent_value = calloc(1, sizeof(runtime_info_value_u));
556
557                 if (runtime_info_item->event_subscription->most_recent_value == NULL) {
558                         LOGE("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
559                         return;
560                 }
561         }
562
563         if (dispatch_event == true && runtime_info_item->event_subscription->changed_cb != NULL) {
564                 memcpy(runtime_info_item->event_subscription->most_recent_value, &current_value, sizeof(runtime_info_value_u));
565                 runtime_info_item->event_subscription->changed_cb(key, runtime_info_item->event_subscription->user_data);
566         }
567 }