Apply hal-api-device-memory module HAL ABI versioning
[platform/core/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_INTERNAL_KEY_WIFI_STATUS, /**<Indicates the current status of Wi-Fi. */
58         RUNTIME_INFO_DATA_TYPE_INT,
59         runtime_info_wifi_status_get_value,
60         runtime_info_wifi_status_set_event_cb,
61         runtime_info_wifi_status_unset_event_cb,
62         NULL
63 },
64
65 {
66         RUNTIME_INFO_KEY_BLUETOOTH_ENABLED, /**<Indicates whether Bluetooth is enabled. */
67         RUNTIME_INFO_DATA_TYPE_BOOL,
68         runtime_info_bt_enabled_get_value,
69         runtime_info_bt_enabled_set_event_cb,
70         runtime_info_bt_enabled_unset_event_cb,
71         NULL
72 },
73
74 {
75         RUNTIME_INFO_KEY_WIFI_HOTSPOT_ENABLED, /**<Indicates whether Wi-Fi hotspot is enabled. */
76         RUNTIME_INFO_DATA_TYPE_BOOL,
77         runtime_info_wifi_hotspot_get_value,
78         runtime_info_wifi_hotspot_set_event_cb,
79         runtime_info_wifi_hotspot_unset_event_cb,
80         NULL
81 },
82
83 {
84         RUNTIME_INFO_KEY_BLUETOOTH_TETHERING_ENABLED, /**<Indicates whether Bluetooth tethering is enabled. */
85         RUNTIME_INFO_DATA_TYPE_BOOL,
86         runtime_info_bt_hotspot_get_value,
87         runtime_info_bt_hotspot_set_event_cb,
88         runtime_info_bt_hotspot_unset_event_cb,
89         NULL
90 },
91
92 {
93         RUNTIME_INFO_KEY_USB_TETHERING_ENABLED, /**<Indicates whether USB tethering is enabled. */
94         RUNTIME_INFO_DATA_TYPE_BOOL,
95         runtime_info_usb_hotspot_get_value,
96         runtime_info_usb_hotspot_set_event_cb,
97         runtime_info_usb_hotspot_unset_event_cb,
98         NULL
99 },
100
101 {
102         RUNTIME_INFO_KEY_PACKET_DATA_ENABLED, /**<Indicates Whether the packet data through 3G network is enabled. */
103         RUNTIME_INFO_DATA_TYPE_BOOL,
104         runtime_info_packet_data_get_value,
105         runtime_info_packet_data_set_event_cb,
106         runtime_info_packet_data_unset_event_cb,
107         NULL
108 },
109
110 {
111         RUNTIME_INFO_KEY_DATA_ROAMING_ENABLED, /**<Indicates whether data roaming is enabled. */
112         RUNTIME_INFO_DATA_TYPE_BOOL,
113         runtime_info_data_roaming_get_value,
114         runtime_info_data_roaming_set_event_cb,
115         runtime_info_data_roaming_unset_event_cb,
116         NULL
117 },
118
119 {
120         RUNTIME_INFO_KEY_VIBRATION_ENABLED, /**<Indicates whether vibration is enabled. */
121         RUNTIME_INFO_DATA_TYPE_BOOL,
122         runtime_info_vibration_enabled_get_value,
123         runtime_info_vibration_enabled_set_event_cb,
124         runtime_info_vibration_enabled_unset_event_cb,
125         NULL
126 },
127
128 {
129         RUNTIME_INFO_KEY_AUDIO_JACK_CONNECTED, /**<Indicates whether audio jack is connected. */
130         RUNTIME_INFO_DATA_TYPE_BOOL,
131         runtime_info_audiojack_get_value,
132         runtime_info_audiojack_set_event_cb,
133         runtime_info_audiojack_unset_event_cb,
134         NULL
135 },
136
137 {
138         RUNTIME_INFO_KEY_GPS_STATUS, /**<Indicates the current status of GPS. */
139         RUNTIME_INFO_DATA_TYPE_INT,
140         runtime_info_gps_status_get_value,
141         runtime_info_gps_status_set_event_cb,
142         runtime_info_gps_status_unset_event_cb,
143         NULL
144 },
145
146 {
147         RUNTIME_INFO_KEY_BATTERY_IS_CHARGING, /**<Indicates the battery is currently charging. */
148         RUNTIME_INFO_DATA_TYPE_BOOL,
149         runtime_info_battery_charging_get_value,
150         runtime_info_battery_charging_set_event_cb,
151         runtime_info_battery_charging_unset_event_cb,
152         NULL
153 },
154
155 {
156         RUNTIME_INFO_KEY_TV_OUT_CONNECTED, /**<Indicates whether TV out is connected. */
157         RUNTIME_INFO_DATA_TYPE_BOOL,
158         runtime_info_tvout_connected_get_value,
159         runtime_info_tvout_connected_set_event_cb,
160         runtime_info_tvout_connected_unset_event_cb,
161         NULL
162 },
163
164 {
165         RUNTIME_INFO_KEY_AUDIO_JACK_STATUS, /**<Indicates the current status of audio jack. */
166         RUNTIME_INFO_DATA_TYPE_INT,
167         runtime_info_audio_jack_status_get_value,
168         runtime_info_audio_jack_status_set_event_cb,
169         runtime_info_audio_jack_status_unset_event_cb,
170         NULL
171 },
172
173 {
174         RUNTIME_INFO_KEY_USB_CONNECTED, /**<Indicates whether usb is connected. */
175         RUNTIME_INFO_DATA_TYPE_BOOL,
176         runtime_info_usb_connected_get_value,
177         runtime_info_usb_connected_set_event_cb,
178         runtime_info_usb_connected_unset_event_cb,
179         NULL
180 },
181
182 {
183         RUNTIME_INFO_KEY_CHARGER_CONNECTED, /**<Indicates whether charger is connected. */
184         RUNTIME_INFO_DATA_TYPE_BOOL,
185         runtime_info_charger_connected_get_value,
186         runtime_info_charger_connected_set_event_cb,
187         runtime_info_charger_connected_unset_event_cb,
188         NULL
189 },
190
191 {
192         RUNTIME_INFO_KEY_AUTO_ROTATION_ENABLED, /**<Indicates whether auto rotation is enabled. */
193         RUNTIME_INFO_DATA_TYPE_BOOL,
194         runtime_info_auto_rotation_enabled_get_value,
195         runtime_info_auto_rotation_enabled_set_event_cb,
196         runtime_info_auto_rotation_enabled_unset_event_cb,
197         NULL
198 },
199
200 {
201         RUNTIME_INFO_MAX, RUNTIME_INFO_DATA_TYPE_INT, NULL, NULL, NULL, NULL
202 }
203
204 };
205
206 static int runtime_info_get_item(runtime_info_key_e key, runtime_info_item_h *runtime_info_item)
207 {
208         int index = 0;
209
210         while (runtime_info_item_table[index].key != RUNTIME_INFO_MAX) {
211                 if (runtime_info_item_table[index].key == key) {
212                         *runtime_info_item = &runtime_info_item_table[index];
213                         return 0;
214                 }
215
216                 index++;
217         }
218
219         return -1;
220 }
221
222 int runtime_info_get_value(runtime_info_key_e key, runtime_info_data_type_e data_type, runtime_info_value_h value)
223 {
224         runtime_info_item_h runtime_info_item;
225         runtime_info_func_get_value get_value;
226         int ret;
227
228         if (runtime_info_get_item(key, &runtime_info_item))     {
229                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
230                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
231         }
232
233         if (runtime_info_item->data_type != data_type) {
234                 LOGE("INVALID_PARAMETER(0x%08x) : invalid data type", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
235                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
236         }
237
238         get_value = runtime_info_item->get_value;
239
240         if (get_value == NULL) {
241                 LOGE("IO_ERROR(0x%08x) : failed to call getter for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
242                 return RUNTIME_INFO_ERROR_IO_ERROR;
243         }
244
245         ret = get_value(value);
246         if (ret != RUNTIME_INFO_ERROR_NONE)
247                 LOGE("IO_ERROR(0x%08x) : failed to get the runtime informaion / key(%d)", ret, key);
248
249         return ret;
250 }
251
252 API int runtime_info_get_value_int(runtime_info_key_e key, int *value)
253 {
254         int retcode;
255         runtime_info_value_u runtime_info_value;
256
257         if (value == NULL) {
258                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
259                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
260         }
261
262         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_INT, &runtime_info_value);
263
264         if (retcode == RUNTIME_INFO_ERROR_NONE)
265                 *value = runtime_info_value.i;
266
267         return retcode;
268 }
269
270 API int runtime_info_get_value_bool(runtime_info_key_e key, bool *value)
271 {
272         int retcode;
273         runtime_info_value_u runtime_info_value;
274
275         if (value == NULL) {
276                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
277                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
278         }
279
280         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_BOOL, &runtime_info_value);
281
282         if (retcode == RUNTIME_INFO_ERROR_NONE)
283                 *value = runtime_info_value.b;
284
285         return retcode;
286 }
287
288 API int runtime_info_get_value_double(runtime_info_key_e key, double *value)
289 {
290         int retcode;
291         runtime_info_value_u runtime_info_value;
292
293         if (value == NULL) {
294                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
295                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
296         }
297
298         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_DOUBLE, &runtime_info_value);
299
300         if (retcode == RUNTIME_INFO_ERROR_NONE)
301                 *value = runtime_info_value.d;
302
303         return retcode;
304 }
305
306 API int runtime_info_get_value_string(runtime_info_key_e key, char **value)
307 {
308         int retcode;
309         runtime_info_value_u runtime_info_value;
310
311         if (value == NULL) {
312                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
313                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
314         }
315
316         retcode = runtime_info_get_value(key, RUNTIME_INFO_DATA_TYPE_STRING, &runtime_info_value);
317
318         if (retcode == RUNTIME_INFO_ERROR_NONE)
319                 *value = runtime_info_value.s;
320
321         return retcode;
322 }
323
324 API int runtime_info_set_changed_cb(runtime_info_key_e key, runtime_info_changed_cb callback, void *user_data)
325 {
326         runtime_info_item_h runtime_info_item;
327         runtime_info_func_set_event_cb set_event_cb;
328         bool subscribe_event = false;
329         int ret;
330
331         if (callback == NULL) {
332                 LOGE("INVALID_PARAMETER(0x%08x)", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
333                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
334         }
335
336         if (runtime_info_get_item(key, &runtime_info_item))     {
337                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
338                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
339         }
340
341         set_event_cb = runtime_info_item->set_event_cb;
342
343         if (set_event_cb == NULL) {
344                 LOGE("IO_ERROR(0x%08x) : failed to set callback for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
345                 return RUNTIME_INFO_ERROR_IO_ERROR;
346         }
347
348         if (runtime_info_item->event_subscription == NULL) {
349                 subscribe_event = true;
350
351                 runtime_info_event_subscription_h event_subscription;
352                 event_subscription = calloc(1, sizeof(runtime_info_event_subscription_s));
353
354                 if (event_subscription == NULL) {
355                         LOGE("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
356                         return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
357                 }
358
359                 runtime_info_item->event_subscription = event_subscription;
360         }
361
362         runtime_info_item->event_subscription->changed_cb = callback;
363         runtime_info_item->event_subscription->user_data = user_data;
364
365         if (runtime_info_item->event_subscription->most_recent_value != NULL)
366                 free(runtime_info_item->event_subscription->most_recent_value);
367         runtime_info_item->event_subscription->most_recent_value = NULL;
368
369         if (!subscribe_event)
370                 return RUNTIME_INFO_ERROR_NONE;
371
372         ret = set_event_cb();
373         if (ret != RUNTIME_INFO_ERROR_NONE) {
374                 _E("Failed to set event hadler (%d)", ret);
375                 return ret;
376         }
377
378         runtime_info_item->event_subscription->most_recent_value =
379                 calloc(1, sizeof(runtime_info_value_u));
380         if (!runtime_info_item->event_subscription->most_recent_value) {
381                 LOGE("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
382                 runtime_info_item->unset_event_cb();
383                 return RUNTIME_INFO_ERROR_OUT_OF_MEMORY;
384         }
385
386         ret = runtime_info_item->get_value(runtime_info_item->event_subscription->most_recent_value);
387         if (ret != RUNTIME_INFO_ERROR_NONE) {
388                 LOGE("Failed to get current value (%d)", ret);
389                 runtime_info_item->unset_event_cb();
390                 free(runtime_info_item->event_subscription->most_recent_value);
391                 runtime_info_item->event_subscription->most_recent_value = NULL;
392                 return ret;
393         }
394
395         return RUNTIME_INFO_ERROR_NONE;
396 }
397
398 API int runtime_info_unset_changed_cb(runtime_info_key_e key)
399 {
400         runtime_info_item_h runtime_info_item;
401         runtime_info_func_unset_event_cb unset_event_cb;
402
403         if (runtime_info_get_item(key, &runtime_info_item))     {
404                 LOGE("INVALID_PARAMETER(0x%08x) : invalid key", RUNTIME_INFO_ERROR_INVALID_PARAMETER);
405                 return RUNTIME_INFO_ERROR_INVALID_PARAMETER;
406         }
407
408         if (runtime_info_item->event_subscription != NULL) {
409                 if (runtime_info_item->event_subscription->most_recent_value != NULL) {
410                         free(runtime_info_item->event_subscription->most_recent_value);
411                         runtime_info_item->event_subscription->most_recent_value = NULL;
412                 }
413
414                 free(runtime_info_item->event_subscription);
415                 runtime_info_item->event_subscription = NULL;
416         }
417
418         unset_event_cb = runtime_info_item->unset_event_cb;
419
420         if (unset_event_cb == NULL)     {
421                 LOGE("IO_ERROR(0x%08x) : failed to unset callback for the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
422                 return RUNTIME_INFO_ERROR_IO_ERROR;
423         }
424
425         unset_event_cb();
426
427         return RUNTIME_INFO_ERROR_NONE;
428 }
429
430 //LCOV_EXCL_START : Not called callback
431 void runtime_info_updated(runtime_info_key_e key)
432 {
433         runtime_info_item_h runtime_info_item;
434         runtime_info_value_u current_value;
435         bool dispatch_event = true;
436         int retcode;
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;
441         }
442
443         if (runtime_info_item->event_subscription == NULL) {
444                 LOGE("IO_ERROR(0x%08x) : invalid event subscription", RUNTIME_INFO_ERROR_IO_ERROR);
445                 return;
446         }
447
448         memset(&current_value, 0, sizeof(runtime_info_value_u));
449
450         retcode = runtime_info_get_value(key, runtime_info_item->data_type, &current_value);
451
452         if (retcode != RUNTIME_INFO_ERROR_NONE) {
453                 LOGE("IO_ERROR(0x%08x) : failed to get the runtime information", RUNTIME_INFO_ERROR_IO_ERROR);
454                 return;
455         }
456
457         if (runtime_info_item->event_subscription->most_recent_value != NULL) {
458                 if (!memcmp(runtime_info_item->event_subscription->most_recent_value, &current_value, sizeof(runtime_info_value_u)))
459                         dispatch_event = false;
460         } else {
461                 runtime_info_item->event_subscription->most_recent_value = calloc(1, sizeof(runtime_info_value_u));
462
463                 if (runtime_info_item->event_subscription->most_recent_value == NULL) {
464                         LOGE("OUT_OF_MEMORY(0x%08x)", RUNTIME_INFO_ERROR_OUT_OF_MEMORY);
465                         return;
466                 }
467         }
468
469         if (dispatch_event == true && runtime_info_item->event_subscription->changed_cb != NULL) {
470                 memcpy(runtime_info_item->event_subscription->most_recent_value, &current_value, sizeof(runtime_info_value_u));
471                 runtime_info_item->event_subscription->changed_cb(key, runtime_info_item->event_subscription->user_data);
472         }
473 }
474 //LCOV_EXCL_STOP