Merge "Parameter Check Correction" into tizen
[platform/core/api/batterymonitor.git] / src / battery_monitor.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  */
17
18 #include <glib.h>
19 #include <stdio.h>
20 #include <pthread.h>
21
22 #include "battery_monitor.h"
23 #include "battery_monitor_util.h"
24
25 #define BATTERY_MONITOR_RESOURCE_ID_MAX (BATTERY_MONITOR_RESOURCE_ID_HRM_SENSOR + 1)
26 #define BATTERY_MONITOR_DURATION_TYPE_MAX (BATTERY_MONITOR_DURATION_TYPE_1WEEK + 1)
27
28 static BatteryMonitor *bm_server = NULL;
29 static GDBusConnection *connection = NULL;
30 static int instance_count = 0;
31 static pthread_mutex_t bm_proxy_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
32
33 static void battery_monitor_destroy_instance()
34 {
35         ENTER;
36
37         g_object_unref(connection);
38         connection = NULL;
39
40         g_object_unref(bm_server);
41         bm_server = NULL;
42
43         EXIT;
44         return;
45 }
46
47 static void battery_monitor_release_instance()
48 {
49         pthread_mutex_lock(&bm_proxy_instance_mutex);
50         BATTERY_MONITOR_DECREASE_COUNT(instance_count);
51
52         _INFO("instance count - %d", instance_count);
53
54         if (instance_count <= 0)
55                 battery_monitor_destroy_instance();
56
57         pthread_mutex_unlock(&bm_proxy_instance_mutex);
58 }
59
60 static BatteryMonitor* battery_monitor_get_instance()
61 {
62         pthread_mutex_lock(&bm_proxy_instance_mutex);
63
64         if (bm_server != NULL) {
65                 _DBG("server instance available");
66                 BATTERY_MONITOR_INCREASE_COUNT(instance_count);
67                 pthread_mutex_unlock(&bm_proxy_instance_mutex);
68                 return bm_server;
69         }
70
71 #if !GLIB_CHECK_VERSION(2, 35, 0)
72         g_type_init();
73 #endif
74
75         GError *error = NULL;
76
77         connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
78
79         _INFO("after g_bus_get_sync");
80
81         if (!connection) {
82                 if (error) {
83                         _ERR("Unable to connect to gdbus: %s", error->message);
84                         g_clear_error(&error);
85                 }
86                 pthread_mutex_unlock(&bm_proxy_instance_mutex);
87                 return NULL;
88         }
89
90         g_clear_error(&error);
91
92         /* create server object */
93         bm_server = battery_monitor_proxy_new_sync(connection, G_DBUS_PROXY_FLAGS_NONE,
94                                 BATTERY_MONITOR_DBUS_NAME, BATTERY_MONITOR_DBUS_PATH, NULL, &error);
95
96         if (!bm_server) {
97                 if (error) {
98                         _ERR("Unable account_manager_proxy_new_sync: %s", error->message);
99                         g_clear_error(&error);
100                 }
101                 if (connection) {
102                         g_object_unref(connection);
103                         connection = NULL;
104                 }
105                 pthread_mutex_unlock(&bm_proxy_instance_mutex);
106                 return NULL;
107         }
108
109         g_clear_error(&error);
110
111         BATTERY_MONITOR_INCREASE_COUNT(instance_count);
112
113         pthread_mutex_unlock(&bm_proxy_instance_mutex);
114
115         EXIT;
116         return bm_server;
117 }
118
119 BM_API int battery_monitor_create(battery_monitor_h *handle)
120 {
121         ENTER;
122
123         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
124
125         BM_CHECK_INPUT_PARAM(handle);
126
127         battery_monitor_total_consumption_s *data_handle = \
128                 (battery_monitor_total_consumption_s *)calloc(1, sizeof(battery_monitor_total_consumption_s));
129
130         BM_RETURN_VAL((data_handle != NULL), {}, BATTERY_MONITOR_ERROR_OUT_OF_MEMORY, "memory allocation failed");
131
132         data_handle->ble_val = 0;
133         data_handle->wifi_val = 0;
134         data_handle->cpu_val = 0;
135         data_handle->dp_val = 0;
136         data_handle->dn_val = 0;
137 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
138         data_handle->gps_val = 0;
139         data_handle->hrm_val = 0;
140         data_handle->bat_val = 0;
141 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
142
143         *handle = (battery_monitor_h)data_handle;
144
145         EXIT;
146         return BATTERY_MONITOR_ERROR_NONE;
147 }
148
149 BM_API int battery_monitor_destroy(battery_monitor_h handle)
150 {
151         ENTER;
152
153         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
154
155         BM_CHECK_INPUT_PARAM(handle);
156
157         battery_monitor_h data_handle = handle;
158
159         BM_FREE(data_handle);
160
161         EXIT;
162         return BATTERY_MONITOR_ERROR_NONE;
163 }
164
165 BM_API int battery_monitor_get_usage_for_resource_id(battery_monitor_h handle, battery_monitor_resource_id_e resource_id, int *battery_usage)
166 {
167         ENTER;
168
169         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
170
171         BM_CHECK_INPUT_PARAM(handle);
172         BM_CHECK_INPUT_PARAM(battery_usage);
173
174         if (resource_id >= BATTERY_MONITOR_RESOURCE_ID_MAX) {
175                 _ERR("Unknown resource id specified");
176                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
177         }
178
179         battery_monitor_total_consumption_s *data_handle = \
180                                 (battery_monitor_total_consumption_s *)handle;
181
182         switch (resource_id) {
183         case BATTERY_MONITOR_RESOURCE_ID_BLE:
184                 *battery_usage = data_handle->ble_val;
185                 break;
186         case BATTERY_MONITOR_RESOURCE_ID_WIFI:
187                 *battery_usage = data_handle->wifi_val;
188                 break;
189         case BATTERY_MONITOR_RESOURCE_ID_CPU:
190                 *battery_usage = data_handle->cpu_val;
191                 break;
192         case BATTERY_MONITOR_RESOURCE_ID_DISPLAY:
193                 *battery_usage = data_handle->dp_val;
194                 break;
195         case BATTERY_MONITOR_RESOURCE_ID_DEVICE_NETWORK:
196                 *battery_usage = data_handle->dn_val;
197                 break;
198 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
199         case BATTERY_MONITOR_RESOURCE_ID_GPS_SENSOR:
200                 *battery_usage = data_handle->gps_val;
201                 break;
202         case BATTERY_MONITOR_RESOURCE_ID_HRM_SENSOR:
203                 *battery_usage = data_handle->hrm_val;
204                 break;
205         case BATTERY_MONITOR_RESOURCE_ID_BATTERY:
206                 *battery_usage = data_handle->bat_val;
207                 break;
208  #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
209         default:
210                 break;
211         }
212
213         EXIT;
214         return BATTERY_MONITOR_ERROR_NONE;
215 }
216
217 BM_API int battery_monitor_get_usage_by_app_id_for_all_resource_id(char* app_id, battery_monitor_duration_type_e duration, battery_monitor_h *handle)
218 {
219         ENTER;
220
221         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
222
223         BM_CHECK_INPUT_PARAM(app_id);
224         BM_CHECK_INPUT_PARAM(handle);
225         BM_RETURN_VAL((duration < BATTERY_MONITOR_DURATION_TYPE_MAX), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid duration");
226
227         _INFO("total consumption requested for [%s] for duration [%d]", app_id, duration);
228
229         int error_code = BATTERY_MONITOR_ERROR_NONE;
230         GError *error = NULL;
231
232         bm_server = battery_monitor_get_instance();
233         BM_CATCH_ERROR((bm_server != NULL), {}, BATTERY_MONITOR_ERROR_PERMISSION_DENIED, "Failed to get dbus.");
234
235         GVariant *handle_variant = NULL;
236
237         _INFO("before IPC call - get_all_resource_usage_sync()");
238
239         bool is_success = battery_monitor_call_get_all_resource_usage_sync(bm_server, app_id, duration,
240                                         (int)getuid(), &handle_variant, NULL, &error);
241
242         battery_monitor_release_instance();
243
244         _INFO("after IPC call - get_all_resource_usage_sync()");
245
246         BM_CATCH_ERROR((is_success != false), {}, battery_monitor_get_error_code(is_success, error), "Failed to get dbus.");
247         g_clear_error(&error);
248
249         battery_monitor_total_consumption_s *data_handle = \
250                 (battery_monitor_total_consumption_s *)calloc(1, sizeof(battery_monitor_total_consumption_s));
251
252         BM_RETURN_VAL((data_handle != NULL), {}, BATTERY_MONITOR_ERROR_OUT_OF_MEMORY, "memory allocation failed");
253
254         _INFO("before un-marshal data");
255
256         unmarshal_serialized_data(handle_variant, data_handle);
257         g_variant_unref(handle_variant);
258
259         _INFO("after un-marshal data");
260
261         *handle = (battery_monitor_h)data_handle;
262
263         _INFO("battery_get_usage_by_app_id_for_all_resource_id() - SUCCESS");
264
265         EXIT;
266         return BATTERY_MONITOR_ERROR_NONE;
267 CATCH:
268         g_clear_error(&error);
269         _ERR("battery_monitor_call_get_all_resource_usage_sync()=[%d]", error_code);
270         return error_code;
271 }
272
273 BM_API int battery_monitor_get_usage_by_app_id_for_resource_id(char* app_id, battery_monitor_resource_id_e resource_id,
274                                                                 battery_monitor_duration_type_e duration, int* battery_usage)
275 {
276         ENTER;
277
278         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
279
280         BM_CHECK_INPUT_PARAM(app_id);
281         BM_CHECK_INPUT_PARAM(battery_usage);
282
283         if (resource_id >= BATTERY_MONITOR_RESOURCE_ID_MAX) {
284                 _ERR("Unknown resource id specified");
285                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
286         }
287
288         if (duration >= BATTERY_MONITOR_DURATION_TYPE_MAX) {
289                 _ERR("Unknown duration specified");
290                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
291         }
292
293         int battery_consumption = 0;
294         int error_code = BATTERY_MONITOR_ERROR_NONE;
295         GError *error = NULL;
296
297         bm_server = battery_monitor_get_instance();
298         BM_CATCH_ERROR((bm_server != NULL), {}, BATTERY_MONITOR_ERROR_PERMISSION_DENIED, "Failed to get dbus.");
299
300         _INFO("before IPC call - app_id(%s), resource_id(%d), duration(%d)", app_id, resource_id, duration);
301
302         bool is_success = battery_monitor_call_get_usage_by_app_id_for_resource_id_sync(bm_server, app_id, resource_id,
303                                         duration, (int)getuid(), &battery_consumption, NULL, &error);
304
305         battery_monitor_release_instance();
306
307         _INFO("after IPC call - battery_consumption(%d)", battery_consumption);
308
309         BM_CATCH_ERROR((is_success != false), {}, battery_monitor_get_error_code(is_success, error), "Failed to get dbus.");
310         g_clear_error(&error);
311
312         *battery_usage = battery_consumption;
313
314         _INFO("battery_get_usage_by_app_id_for_resource_id() - SUCCESS");
315
316         EXIT;
317         return BATTERY_MONITOR_ERROR_NONE;
318 CATCH:
319         g_clear_error(&error);
320         _ERR("battery_monitor_call_get_usage_by_app_id_for_resource_id_sync()=[%d]", error_code);
321         return error_code;
322 }
323
324 BM_API int battery_monitor_get_total_usage_by_app_id(char* app_id, battery_monitor_duration_type_e duration, int* battery_usage)
325 {
326         ENTER;
327
328         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
329
330         BM_CHECK_INPUT_PARAM(app_id);
331         BM_CHECK_INPUT_PARAM(battery_usage);
332
333         if (duration >= BATTERY_MONITOR_DURATION_TYPE_MAX) {
334                 _ERR("Unknown duration specified");
335                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
336         }
337
338         int battery_consumption = 0;
339         int error_code = BATTERY_MONITOR_ERROR_NONE;
340         GError *error = NULL;
341
342         bm_server = battery_monitor_get_instance();
343         BM_CATCH_ERROR((bm_server != NULL), {}, BATTERY_MONITOR_ERROR_PERMISSION_DENIED, "Failed to get dbus.");
344
345         _INFO("before IPC call - app_id(%s), duration(%d)", app_id, duration);
346
347         bool is_success = battery_monitor_call_get_total_usage_by_app_id_sync(bm_server, app_id, duration,
348                                         (int)getuid(), &battery_consumption, NULL, &error);
349
350         battery_monitor_release_instance();
351
352         _INFO("after IPC call - battery_consumption(%d)", battery_consumption);
353
354         *battery_usage = battery_consumption;
355
356         BM_CATCH_ERROR((is_success != false), {}, battery_monitor_get_error_code(is_success, error), "Failed to get dbus.");
357         g_clear_error(&error);
358
359         _INFO("battery_monitor_call_get_total_usage_by_app_id_sync() - SUCCESS");
360
361         EXIT;
362         return BATTERY_MONITOR_ERROR_NONE;
363 CATCH:
364         g_clear_error(&error);
365         _ERR("battery_monitor_call_get_total_usage_by_app_id_sync()=[%d]", error_code);
366         return error_code;
367 }
368
369 BM_API int battery_monitor_get_total_usage_by_resource_id(battery_monitor_resource_id_e resource_id,
370                                                         battery_monitor_duration_type_e duration, int* battery_usage)
371 {
372         ENTER;
373
374         CHECK_BATTERY_FEATURE_SUPPORTED(BATTERY_FEATURE);
375
376         BM_CHECK_INPUT_PARAM(battery_usage);
377
378         if (resource_id >= BATTERY_MONITOR_RESOURCE_ID_MAX) {
379                 _ERR("Unknown resource id specified");
380                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
381         }
382
383         if (duration >= BATTERY_MONITOR_DURATION_TYPE_MAX) {
384                 _ERR("Unknown duration specified");
385                 return BATTERY_MONITOR_ERROR_INVALID_PARAMETER;
386         }
387
388         int battery_consumption = 0;
389         int error_code = BATTERY_MONITOR_ERROR_NONE;
390         GError *error = NULL;
391
392         bm_server = battery_monitor_get_instance();
393         BM_CATCH_ERROR((bm_server != NULL), {}, BATTERY_MONITOR_ERROR_PERMISSION_DENIED, "Failed to get dbus.");
394
395         _INFO("before IPC call - resource_id(%d), duration(%d)", resource_id, duration);
396
397         bool is_success = battery_monitor_call_get_total_usage_by_resource_id_sync(bm_server, resource_id, duration,
398                                         (int)getuid(), &battery_consumption, NULL, &error);
399
400         battery_monitor_release_instance();
401
402         _INFO("after IPC call - battery_consumption(%d)", battery_consumption);
403
404         *battery_usage = battery_consumption;
405
406         BM_CATCH_ERROR((is_success != false), {}, battery_monitor_get_error_code(is_success, error), "Failed to get dbus.");
407         g_clear_error(&error);
408
409         _INFO("battery_get_total_usage_by_resource_id() - SUCCESS");
410
411         EXIT;
412         return BATTERY_MONITOR_ERROR_NONE;
413 CATCH:
414         g_clear_error(&error);
415         _ERR("battery_monitor_call_get_total_usage_by_resource_id_sync()=[%d]", error_code);
416         return error_code;
417 }