4 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <device/battery-internal.h>
23 #define METHOD_BATTERY_TIMETOFULL "TimeToFull"
24 #define METHOD_BATTERY_TIMETOEMPTY "TimeToEmpty"
25 #define METHOD_BATTERY_SETLOWBATLEVEL "SetLowbatLevel"
26 #define METHOD_BATTERY_GETLOWBATLEVEL "GetLowbatLevel"
27 #define METHOD_BATTERY_CHARGERSTATUS "ChargerStatus"
28 #define METHOD_BATTERY_CHARGENOW "ChargeNow"
29 #define METHOD_BATTERY_STATUSLOW "BatteryStatusLow"
30 #define METHOD_BATTERY_GETPERCENT "GetPercent"
31 #define METHOD_BATTERY_GETPERCENTRAW "GetPercentRaw"
32 #define METHOD_BATTERY_ISFULL "IsFull"
33 #define METHOD_BATTERY_HEALTH "GetHealth"
34 #define METHOD_BATTERY_GETINFO "GetBatteryInfo"
35 #define METHOD_BATTERY_GETINFO_DIRECT "GetBatteryInfoDirect"
36 #define METHOD_BATTERY_POWERSUPPLY "power_supply"
37 #define METHOD_BATTERY_GET_POWERSUPPLY "get_power_supply"
40 #define CHARGEFULL "Full"
41 #define CHARGENOW "Charging"
42 #define DISCHARGE "Discharging"
43 #define NOTCHARGE "Not charging"
47 #define OVERHEAT "Overheat"
48 #define TEMPCOLD "Cold"
49 #define OVERVOLT "Over voltage"
52 #define TYPE_UNKNOWN "0"
53 #define TYPE_BATTERY "1"
55 #define TYPE_MAINS "3"
58 //External Power Source
61 #define WIRELESS "wireless"
65 #define VOLT_4P2 "4200000"
66 #define VOLT_3P6 "3700000"
67 #define VOLT_3P4 "3500000"
68 #define VOLT_3P2 "3200000"
69 #define VOLT_3P0 "3000000"
72 #define TEMP_800 "800"
73 #define TEMP_250 "250"
82 #define PRESENT_ABNORMAL "0"
83 #define PRESENT_NORMAL "1"
86 #define MISC_ABNORMAL "1"
87 #define MISC_NORMAL "0"
95 #define DEFAULT_NORMAL 100
96 #define DEFAULT_WARNING 15
97 #define DEFAULT_CRITICAL 5
98 #define DEFAULT_POWEROFF 1
99 #define DEFAULT_REALOFF 0
102 #define CHARGER_WIRELESS_TYPE_BT 10
103 #define CHARGER_WIRELESS_TYPE_3G 22
104 #define CHARGER_INCOMPATIBLE_TYPE 11
105 #define CHARGER_D2D_TYPE 110
106 #define WIRELESS_CHARGER_CONNECTED 2
111 enum charge_status_type {
112 CHARGE_STATUS_UNKNOWN,
113 CHARGE_STATUS_DISCONNECTED,
114 CHARGE_STATUS_CONNECTED,
115 CHARGE_STATUS_CHARGING,
116 CHARGE_STATUS_DISCHARGING,
117 CHARGE_STATUS_NOT_CHARGING,
121 enum charge_now_type {
122 CHARGER_ABNORMAL = -1,
137 CHARGER_TYPE_NONE = 0,
139 CHARGER_TYPE_WIRELESS,
140 CHARGER_TYPE_INCOMPATIBLE,
144 static struct power_supply_type {
145 const char *scenario;
147 const char *capacity;
148 const char *charge_status;
152 const char *power_source;
153 const char *voltage_now;
154 const char *voltage_avg;
155 const char *current_now;
156 const char *current_avg;
157 const char *temperature;
159 const char *freq_strength;
161 } power_supply_types[] = {
162 {"norm", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"},
163 {"norm", S_ENTER, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
164 {"norm", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, NULL}, /* init */
165 {"heat1", S_ENTER, "100", DISCHARGE, OVERHEAT, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, NULL},
166 {"heat1", S_ENTER, "100", NOTCHARGE, OVERHEAT, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, "HEALTH(H) BEFORE CHARGE"},
167 {"heat1", S_LEAVE, "100", DISCHARGE, OVERHEAT, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
168 {"heat1", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, NULL}, /* init */
170 {"heat2", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_800, MISC_NORMAL, LEVEL_0, NULL},
171 {"heat2", S_ENTER, "100", NOTCHARGE, OVERHEAT, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, "HEALTH(H) AFTER CHARGE"},
172 {"heat2", S_LEAVE, "100", DISCHARGE, OVERHEAT, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
173 {"heat2", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_800, MISC_NORMAL, LEVEL_0, NULL}, /* init */
175 {"cold1", S_ENTER, "100", DISCHARGE, TEMPCOLD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, NULL},
176 {"cold1", S_ENTER, "100", NOTCHARGE, TEMPCOLD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, "HEALTH(L) BEFORE CHARGE"},
177 {"cold1", S_LEAVE, "100", DISCHARGE, TEMPCOLD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
178 {"cold1", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, NULL}, /* init */
180 {"cold2", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_0, MISC_NORMAL, LEVEL_0, NULL},
181 {"cold2", S_ENTER, "100", NOTCHARGE, TEMPCOLD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, "HEALTH(L) AFTER CHARGE"},
182 {"cold2", S_LEAVE, "100", DISCHARGE, TEMPCOLD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
183 {"cold2", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_0, MISC_NORMAL, LEVEL_0, NULL}, /* init */
185 {"ovp", S_ENTER, "100", DISCHARGE, OVERVOLT, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "OVP"},
186 {"ovp", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, NULL}, /* init */
188 {"pres1", S_ENTER, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_ABNORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, NULL},
189 {"pres1", S_ENTER, "100", NOTCHARGE, GOOD, TYPE_UPS, PRESENT_ABNORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "PRESENT BEFORE CHARGE"},
190 {"pres1", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_ABNORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
191 {"pres1", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, NULL}, /* init */
193 {"pres2", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, NULL},
194 {"pres2", S_ENTER, "100", NOTCHARGE, GOOD, TYPE_UPS, PRESENT_ABNORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "PRESENT AFTER CHARGE"},
195 {"pres2", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_ABNORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"},
196 {"pres2", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, NULL}, /* init */
198 {"bat15", S_ENTER, "15", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_3P6, VOLT_3P6, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 15%"}, /* lowbat 15% */
199 {"bat15", S_LEAVE, "15", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, NONE, VOLT_3P6, VOLT_3P6, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 15%"},
200 {"bat5", S_ENTER, "5", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_3P4, VOLT_3P4, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 5%"}, /* lowbat 5% */
201 {"bat5", S_LEAVE, "5", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, NONE, VOLT_3P4, VOLT_3P4, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 5%"},
202 {"bat3", S_ENTER, "3", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_3P2, VOLT_3P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 3%"}, /* lowbat 3% */
203 {"bat3", S_LEAVE, "3", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, NONE, VOLT_3P2, VOLT_3P2, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 3%"},
204 {"bat1", S_ENTER, "1", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, NONE, VOLT_3P0, VOLT_3P0, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 1%"}, /* lowbat 1% */
205 {"bat1", S_LEAVE, "1", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, NONE, VOLT_3P0, VOLT_3P0, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "LOWBAT 1%"},
207 {"ta", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_300, CUR_300, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"}, /* charging */
208 {"ta", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"},/* discharging */
210 {"full", S_ENTER, "100", CHARGEFULL, GOOD, TYPE_UPS, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"}, /* full */
211 {"full", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"},/* discharging */
213 {"capa", S_ENTER, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "CAPACITY"},/* discharging */
214 {"capa", S_LEAVE, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, USB, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_0, "CAPACITY"},/* charging */
216 {"freq", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_0, "CHARGE"},
217 {"freq", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_1, "FREQ LEVEL 1 AFTER CHARGE"},
218 {"freq", S_ENTER, "100", CHARGENOW, GOOD, TYPE_UPS, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_100, CUR_100, TEMP_250, MISC_NORMAL, LEVEL_2, "FREQ LEVEL 2 AFTER CHARGE"},
219 {"freq", S_LEAVE, "100", DISCHARGE, GOOD, TYPE_BATTERY, PRESENT_NORMAL, WIRELESS, VOLT_4P2, VOLT_4P2, CUR_0, CUR_0, TEMP_250, MISC_NORMAL, LEVEL_0, "DISCHARGE"}, /* init */
222 static bool get_battery_method(const char *method, int *value)
224 GVariant *msg = NULL;
229 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
230 DEVICED_PATH_BATTERY,
231 DEVICED_INTERFACE_BATTERY,
234 _E("Failed to call dbus method(%s): No reply.", method);
238 if (!strncmp(method, METHOD_BATTERY_HEALTH, strlen(METHOD_BATTERY_HEALTH))) {
239 if (!g_variant_get_safe(msg, "(s)", &health)) {
240 _E("Failed to call dbus method(%s): No message.", METHOD_BATTERY_HEALTH);
242 _I("Success. %s=%s", METHOD_BATTERY_HEALTH, health);
248 if (!g_variant_get_safe(msg, "(i)", &val)) {
249 _E("Failed to call dbus method(%s): No message.", method);
251 _I("Success. %s=%d", method, val);
260 g_variant_unref(msg);
265 static bool get_battery_method_vconf(const char *method)
267 GVariant *msg = NULL;
271 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
272 DEVICED_PATH_BATTERY,
273 DEVICED_INTERFACE_BATTERY,
276 _E("Failed to call dbus method(%s): No reply.", method);
280 if (!g_variant_get_safe(msg, "(i)", &val))
281 _E("Failed to call dbus method(%s): No message.", method);
284 _E("Failed to call dbus method(%s): Return fail.", method);
286 _I("Success. %s=%d", method, val);
291 g_variant_unref(msg);
295 static bool get_battery_time_to_full(void)
297 return get_battery_method(METHOD_BATTERY_TIMETOFULL, NULL);
300 static bool get_battery_time_to_empty(void)
302 return get_battery_method(METHOD_BATTERY_TIMETOEMPTY, NULL);
305 static bool get_battery_low_level(int *value)
307 return get_battery_method(METHOD_BATTERY_GETLOWBATLEVEL, value);
310 static bool set_battery_low_level(int newlevel)
318 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
319 DEVICED_PATH_BATTERY,
320 DEVICED_INTERFACE_BATTERY,
321 METHOD_BATTERY_SETLOWBATLEVEL, g_variant_new("(i)", newlevel),
325 _E("Failed to call dbus method(%s): No reply", METHOD_BATTERY_SETLOWBATLEVEL);
329 if (!g_variant_get_safe(msg, "(i)", &val)) {
330 _E("Failed to call dbus method(%s): No message", METHOD_BATTERY_SETLOWBATLEVEL);
333 if (newlevel <= DEFAULT_WARNING) {
335 _I("Success. Can't set low level(%d) smaller than default(%d).", newlevel, DEFAULT_WARNING);
338 _E("Failed. Can't set low level(%d) smaller than default(%d), but returned success.", newlevel, DEFAULT_WARNING);
343 _E("Failed to call dbus method(%s): Return fail.", METHOD_BATTERY_SETLOWBATLEVEL);
349 if (!get_battery_low_level(&getlevel)) {
350 _E("Failed to get battery low level.");
352 if (getlevel == newlevel) {
353 _I("Success : battery low level=%d", newlevel);
356 _E("Failed to set low level(%d). Current low level is %d.", newlevel, getlevel);
360 g_variant_unref(msg);
364 static bool get_battery_charger_status()
366 return get_battery_method_vconf(METHOD_BATTERY_CHARGERSTATUS);
369 static bool get_battery_charge_now()
371 return get_battery_method(METHOD_BATTERY_CHARGENOW, NULL);
374 static bool get_battery_status_low()
376 return get_battery_method_vconf(METHOD_BATTERY_STATUSLOW);
379 static bool get_battery_percent()
381 return get_battery_method(METHOD_BATTERY_GETPERCENT, NULL);
384 static bool get_battery_percent_raw()
386 return get_battery_method(METHOD_BATTERY_GETPERCENTRAW, NULL);
389 static bool get_battery_is_full()
391 return get_battery_method(METHOD_BATTERY_ISFULL, NULL);
394 static bool get_battery_health()
396 return get_battery_method(METHOD_BATTERY_HEALTH, NULL);
399 static bool get_battery_info()
407 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
408 DEVICED_PATH_BATTERY,
409 DEVICED_INTERFACE_BATTERY,
410 METHOD_BATTERY_GETINFO, NULL, &msg);
412 _E("Failed to call dbus method(%s): No reply", METHOD_BATTERY_GETINFO);
416 if (!g_variant_get_safe(msg, "(isssiiiiiiii)", &val[0], //return value
419 &argv[2],//power source
423 &val[4], //current_now
424 &val[5], //current_average
425 &val[6], //voltage_now
426 &val[7], //voltage_average
427 &val[8])) //temperature
428 _E("Failed to call dbus method(%s): No message", METHOD_BATTERY_GETINFO);
431 _E("Failed to call dbus method(%s): Return fail", METHOD_BATTERY_GETINFO);
433 _I("Success: %s %s %s %d %d %d %d %d %d %d %d",
434 argv[0], argv[1], argv[2], val[1], val[2],
435 val[3], val[4], val[5], val[6], val[7],
444 g_variant_unref(msg);
449 static bool get_battery_info_direct(struct device_battery_info *info)
453 ret = device_battery_get_info_direct(info);
455 return capi_result(METHOD_BATTERY_GETINFO_DIRECT, ret);
458 static int change_charge_status_to_enum(const char *env_value)
462 if (env_value == NULL)
465 len = strlen(env_value);
466 if (strncmp(env_value, CHARGEFULL, len) == 0)
467 ret = CHARGE_STATUS_FULL;
468 else if (strncmp(env_value, CHARGENOW, len) == 0)
469 ret = CHARGE_STATUS_CHARGING;
470 else if (strncmp(env_value, DISCHARGE, len) == 0)
471 ret = CHARGE_STATUS_DISCHARGING;
472 else if (strncmp(env_value, NOTCHARGE, len) == 0)
473 ret = CHARGE_STATUS_NOT_CHARGING;
475 ret = CHARGE_STATUS_UNKNOWN;
480 static int change_health_status_to_enum(const char *env_value)
484 if (env_value == NULL)
487 len = strlen(env_value);
488 if (strncmp(env_value, OVERHEAT, len) == 0)
490 else if (strncmp(env_value, TEMPCOLD, len) == 0)
492 else if (strncmp(env_value, OVERVOLT, len) == 0)
494 else if (strncmp(env_value, GOOD, len) == 0)
502 static bool compare_vconf(struct power_supply_type list)
504 int value, ret, temp;
505 int capacity, online, charge_status;
507 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &value);
509 _E("Failed to get vconf value for battery charge now: %d", vconf_get_ext_errno());
512 if (!strcmp(list.charge_status, CHARGEFULL)) {
513 charge_status = CHARGE_STATUS_FULL;
514 temp = CHARGER_DISCHARGING;
515 } else if (!strcmp(list.charge_status, CHARGENOW)) {
516 charge_status = CHARGE_STATUS_CHARGING;
517 temp = CHARGER_CHARGING;
518 } else if (!strcmp(list.charge_status, DISCHARGE)) {
519 charge_status = CHARGE_STATUS_DISCHARGING;
520 temp = CHARGER_DISCHARGING;
521 } else if (!strcmp(list.charge_status, NOTCHARGE)) {
522 charge_status = CHARGE_STATUS_NOT_CHARGING;
523 temp = CHARGER_ABNORMAL;
525 charge_status = CHARGE_STATUS_UNKNOWN;
526 temp = CHARGER_DISCHARGING;
531 capacity = atoi(list.capacity);
532 ret= vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &value);
534 _E("Failed to get vconf value for battery status low: %d", vconf_get_ext_errno());
537 if (capacity <= DEFAULT_REALOFF) {
538 if (charge_status == CHARGE_STATUS_CHARGING)
539 temp = VCONFKEY_SYSMAN_BAT_POWER_OFF;
541 temp = VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF;
542 } else if (capacity <= DEFAULT_POWEROFF) {
543 temp = VCONFKEY_SYSMAN_BAT_POWER_OFF;
544 } else if (capacity <= DEFAULT_CRITICAL) {
545 temp = VCONFKEY_SYSMAN_BAT_CRITICAL_LOW;
546 } else if (capacity <= DEFAULT_WARNING) {
547 temp = VCONFKEY_SYSMAN_BAT_WARNING_LOW;
548 } else if (capacity >= DEFAULT_NORMAL &&
549 charge_status == CHARGE_STATUS_FULL) {
550 temp = VCONFKEY_SYSMAN_BAT_FULL;
552 temp = VCONFKEY_SYSMAN_BAT_NORMAL;
557 ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &value);
559 _E("Failed to get vconf value for charger status: %d", vconf_get_ext_errno());
562 online = atoi(list.online);
563 if (online > atoi(TYPE_BATTERY))
564 temp = VCONFKEY_SYSMAN_CHARGER_CONNECTED;
566 temp = VCONFKEY_SYSMAN_CHARGER_DISCONNECTED;
570 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &value);
572 _E("Failed to get vconf value for battery capacity: %d", vconf_get_ext_errno());
575 if (value != capacity)
578 ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_TYPE, &value);
580 _E("Failed to get vconf value for charger type: %d", vconf_get_ext_errno());
583 if (online <= POWER_SUPPLY_TYPE_BATTERY)
584 temp = CHARGER_TYPE_NONE;
585 else if (online == CHARGER_WIRELESS_TYPE_BT ||
586 online == CHARGER_WIRELESS_TYPE_3G)
587 temp = CHARGER_TYPE_WIRELESS;
588 else if (online == CHARGER_INCOMPATIBLE_TYPE)
589 temp = CHARGER_TYPE_INCOMPATIBLE;
590 else if (online == CHARGER_D2D_TYPE)
591 temp = CHARGER_TYPE_D2D;
593 temp = CHARGER_TYPE_WIRE;
600 static bool compare_power_supply(struct power_supply_type list, int value[], const char *power_source)
602 if (atoi(list.capacity) != value[0]) {
603 _E("Different capacity : %d %d", atoi(list.capacity), value[0]);
607 if (change_charge_status_to_enum(list.charge_status) != value[1]) {
608 _E("Different charge_status : %d %d", change_charge_status_to_enum(list.charge_status), value[1]);
612 if (change_health_status_to_enum(list.health) != value[2]) {
613 _E("Different health : %d %d", change_health_status_to_enum(list.health), value[2]);
617 if (atoi(list.online) != value[3]) {
618 _E("Different online : %d %d", atoi(list.online), value[3]);
622 if (atoi(list.present) != value[4]) {
623 _E("Different present : %d %d", atoi(list.present), value[4]);
627 if (atoi(list.misc) != value[5]) {
628 _E("Different misc : %d %d", atoi(list.misc), value[5]);
632 if (atoi(list.freq_strength) != value[6]) {
633 _E("Different freq_strength : %d %d", atoi(list.freq_strength), value[6]);
637 if (strcmp(list.power_source, power_source)) {
638 _E("Different power_source : %s %s", list.power_source, power_source);
642 if (atoi(list.voltage_now) != value[7]) {
643 _E("Different voltage_now : %d %d", atoi(list.voltage_now), value[7]);
647 if (atoi(list.voltage_avg) != value[8]) {
648 _E("Different voltage_avg : %d %d", atoi(list.voltage_avg), value[8]);
652 if (atoi(list.current_now) != value[9]) {
653 _E("Different current_now : %d %d", atoi(list.current_now), value[9]);
657 if (atoi(list.current_avg) != value[10]) {
658 _E("Different current_avg : %d %d", atoi(list.current_avg), value[10]);
662 if (atoi(list.temperature) != value[11]) {
663 _E("Different temperature : %d %d", atoi(list.temperature), value[11]);
670 static bool set_battery_power_supply(int index)
676 var = g_variant_new("(sisssssssssssss)", POWER_SUBSYSTEM,
678 power_supply_types[index].capacity,
679 power_supply_types[index].charge_status,
680 power_supply_types[index].health,
681 power_supply_types[index].online,
682 power_supply_types[index].present,
683 power_supply_types[index].misc,
684 power_supply_types[index].freq_strength,
685 power_supply_types[index].power_source,
686 power_supply_types[index].voltage_now,
687 power_supply_types[index].voltage_avg,
688 power_supply_types[index].current_now,
689 power_supply_types[index].current_avg,
690 power_supply_types[index].temperature);
691 _I("C(%s) S(%s) H(%s) O(%s) P(%s) M(%s) F(%s) SRC(%s) Vol(%s %s) Cur(%s %s) T(%s)",
692 power_supply_types[index].capacity,
693 power_supply_types[index].charge_status,
694 power_supply_types[index].health,
695 power_supply_types[index].online,
696 power_supply_types[index].present,
697 power_supply_types[index].misc,
698 power_supply_types[index].freq_strength,
699 power_supply_types[index].power_source,
700 power_supply_types[index].voltage_now,
701 power_supply_types[index].voltage_avg,
702 power_supply_types[index].current_now,
703 power_supply_types[index].current_avg,
704 power_supply_types[index].temperature);
706 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
707 DEVICED_PATH_BATTERY,
708 DEVICED_INTERFACE_BATTERY,
709 POWER_SUBSYSTEM, var, &msg);
711 _E("Failed to call dbus method(%s): No reply", POWER_SUBSYSTEM);
715 if (!g_variant_get_safe(msg, "(i)", &val)) {
716 _E("Failed to call dbus method(%s): No message", POWER_SUBSYSTEM);
720 _E("Failed to call dbus method(%s): Return fail(%d)", POWER_SUBSYSTEM, val);
722 _I("Success. val=%d", val);
727 g_variant_unref(msg);
728 sleep(TEST_WAIT_TIME_INTERVAL);
733 static bool get_battery_power_supply(int rsp[], char **power_source)
739 err = dbus_handle_method_sync_with_reply_var(DEVICED_BUS_NAME,
740 DEVICED_PATH_BATTERY,
741 DEVICED_INTERFACE_BATTERY,
742 METHOD_BATTERY_GET_POWERSUPPLY, NULL, &msg);
744 _E("Failed to call dbus method(%s): No reply", METHOD_BATTERY_GET_POWERSUPPLY);
748 if (!g_variant_get_safe(msg, "(iiiiiiiisiiiii)", &val, //return value
750 &rsp[1], //charge_status
755 &rsp[6], //freq_strength
756 power_source, //power_source
757 &rsp[7], //voltage_now
758 &rsp[8], //voltagge_avg
759 &rsp[9], //current_now
760 &rsp[10], //current_avg
761 &rsp[11])) { //temperature
762 _E("Failed to call dbus method(%s): No message", METHOD_BATTERY_GET_POWERSUPPLY);
765 _E("Failed to call dbus method(%s): Return fail(%d)", METHOD_BATTERY_GET_POWERSUPPLY, val);
767 _I("Success : C(%d) S(%d) H(%d) O(%d) P(%d) M(%d) F(%d) SRC(%s) Vol(%d %d) Cur(%d %d) Temp(%d)",
768 rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5], rsp[6], *power_source, rsp[7], rsp[8], rsp[9], rsp[10], rsp[11]);
773 g_variant_unref(msg);
778 static void full_scenario(char *unit, char *capacity, int status)
783 char *power_source = NULL;
785 if (!unit || !capacity)
790 for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
791 if (len != strlen(power_supply_types[index].scenario))
793 if (strncmp(unit, power_supply_types[index].scenario, len) != 0 ||
794 power_supply_types[index].status != status)
796 power_supply_types[index].capacity = capacity;
797 _D("%s", power_supply_types[index].capacity);
798 set_battery_power_supply(index);
799 get_battery_power_supply(rsp, &power_source);
800 compare_power_supply(power_supply_types[index], rsp, power_source);
801 compare_vconf(power_supply_types[index]);
805 void battery_scenario(char *unit, int status)
811 char *power_source = NULL;
812 const char *scenario = NULL;
817 unit_len = strlen(unit);
819 for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
820 if (unit_len != strlen(power_supply_types[index].scenario))
822 scenario = power_supply_types[index].scenario;
823 if (strncmp(unit, scenario, unit_len) != 0 ||
824 power_supply_types[index].status != status)
827 set_battery_power_supply(index);
828 get_battery_power_supply(rsp, &power_source);
829 compare_power_supply(power_supply_types[index], rsp, power_source);
830 compare_vconf(power_supply_types[index]);
836 index = strlen(unit);
837 if (index < 0 || index > 3)
840 index = strtol(unit, NULL, 10);
841 if (index < 0 || index > 100)
844 for (index = 0; index < ARRAY_SIZE(power_supply_types); index++){
845 if (strncmp("capa", power_supply_types[index].scenario, 4) != 0 ||
846 power_supply_types[index].status != status)
848 power_supply_types[index].capacity = unit;
849 _D("%s", power_supply_types[index].capacity);
850 set_battery_power_supply(index);
851 get_battery_power_supply(rsp, &power_source);
852 compare_power_supply(power_supply_types[index], rsp, power_source);
853 compare_vconf(power_supply_types[index]);
857 void battery_test_all(int *success, int *fail)
862 char *power_source = NULL;
863 struct device_battery_info info;
865 (get_battery_time_to_full()) ? s++ : f++;
866 (get_battery_time_to_empty()) ? s++ : f++;
867 (get_battery_low_level(NULL)) ? s++ : f++;
868 (set_battery_low_level(10)) ? s++ : f++;
869 (set_battery_low_level(50)) ? s++ : f++;
870 (get_battery_charger_status()) ? s++ : f++;
871 (get_battery_charge_now()) ? s++ : f++;
872 (get_battery_status_low()) ? s++ : f++;
873 (get_battery_percent()) ? s++ : f++;
874 (get_battery_percent_raw()) ? s++ : f++;
875 (get_battery_is_full()) ? s++ : f++;
876 (get_battery_health()) ? s++ : f++;
877 (get_battery_info()) ? s++ : f++;
878 (get_battery_info_direct(&info)) ? s++ : f++;
880 for (int index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
881 (set_battery_power_supply(index) &&
882 get_battery_power_supply(rsp, &power_source) &&
883 compare_power_supply(power_supply_types[index], rsp, power_source) &&
884 compare_vconf(power_supply_types[index])) ? s++ : f++;
887 if (NULL != success) *success = s;
888 if (NULL != fail) *fail = f;
891 static void battery_init(void *data)
898 battery_test_all(&success, &fail);
900 _I("Total=%d Success=%d Fail=%d", success+fail, success, fail);
903 static void battery_exit(void *data)
909 static int battery_unit(int argc, char **argv)
912 char *power_source = NULL;
913 struct device_battery_info info;
919 battery_test_all(&success, &fail);
920 _I("Total=%d Success=%d Fail=%d", success+fail, success, fail);
921 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_TIMETOFULL)) {
922 get_battery_time_to_full();
923 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_TIMETOEMPTY)) {
924 get_battery_time_to_empty();
925 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETLOWBATLEVEL)) {
926 get_battery_low_level(NULL);
927 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_SETLOWBATLEVEL)) {
928 set_battery_low_level(atoi(argv[4]));
929 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_CHARGERSTATUS)) {
930 get_battery_charger_status();
931 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_CHARGENOW)) {
932 get_battery_charge_now();
933 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_STATUSLOW)) {
934 get_battery_status_low();
935 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETPERCENT)) {
936 get_battery_percent();
937 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETPERCENTRAW)) {
938 get_battery_percent_raw();
939 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_ISFULL)) {
940 get_battery_is_full();
941 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_HEALTH)) {
942 get_battery_health();
943 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETINFO)) {
945 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_GETINFO_DIRECT)) {
946 get_battery_info_direct(&info);
947 } else if (0 == strcasecmp(argv[3], METHOD_BATTERY_POWERSUPPLY)) {
948 for (int index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
949 set_battery_power_supply(index);
950 get_battery_power_supply(rsp, &power_source);
951 compare_power_supply(power_supply_types[index], rsp, power_source);
952 compare_vconf(power_supply_types[index]);
954 } else if (argc > 4 && argv[4] && !strncmp("enter", argv[4], 5)) {
955 battery_scenario(argv[3], S_ENTER);
956 } else if (argc > 4 && argv[4] && !strncmp("leave", argv[4], 5)) {
957 battery_scenario(argv[3], S_LEAVE);
958 } else if (argc >5 && argv[5] && !strncmp("enter", argv[5], 5)) {
959 full_scenario(argv[3], argv[4], S_ENTER);
960 } else if (argc >5 && argv[5] && !strncmp("leave", argv[5], 5)) {
961 full_scenario(argv[3], argv[5], S_LEAVE);
963 _E("Unknown test case.");
969 static const struct test_ops battery_test_ops = {
970 .priority = TEST_PRIORITY_NORMAL,
972 .init = battery_init,
973 .exit = battery_exit,
974 .unit = battery_unit,
977 TEST_OPS_REGISTER(&battery_test_ops)