diff --git a/src/detection/battery/battery_android.c b/src/detection/battery/battery_android.c index aeb9b74d1..b05cce111 100644 --- a/src/detection/battery/battery_android.c +++ b/src/detection/battery/battery_android.c @@ -14,7 +14,7 @@ static inline void wrapYyjsonFree(yyjson_doc** doc) yyjson_doc_free(*doc); } -const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) +static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results) { FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); @@ -47,3 +47,82 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) return NULL; } + +static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + if (ffProcessAppendStdOut(&buf, (char* []) { + "/system/bin/dumpsys", + "battery", + NULL, + }) != NULL || buf.length == 0) + return "Executing `/system/bin/dumpsys battery` failed"; // Only works in `adb shell`, or when rooted + + if (!ffStrbufStartsWithS(&buf, "Current Battery Service state:\n")) + return "Invalid `/system/bin/dumpsys battery` result"; + + const char* start = buf.chars + strlen("Current Battery Service state:\n"); + + FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate(); + if (!ffParsePropLines(start, "present: ", &temp) || !ffStrbufEqualS(&temp, "true")) + return NULL; + ffStrbufClear(&temp); + + BatteryResult* battery = ffListAdd(results); + battery->temperature = FF_BATTERY_TEMP_UNSET; + ffStrbufInit(&battery->manufacturer); + ffStrbufInit(&battery->modelName); + ffStrbufInit(&battery->status); + ffStrbufInit(&battery->technology); + + if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true")) + ffStrbufAppendS(&battery->status, "AC powered"); + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "USB powered: ", &temp) && ffStrbufEqualS(&temp, "true")) + { + if (battery->status.length) ffStrbufAppendS(&battery->status, ", "); + ffStrbufAppendS(&battery->status, "USB powered"); + } + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "Wireless powered: ", &temp) && ffStrbufEqualS(&temp, "true")) + { + if (battery->status.length) ffStrbufAppendS(&battery->status, ", "); + ffStrbufAppendS(&battery->status, "Wireless powered"); + } + ffStrbufClear(&temp); + + { + double level = 0, scale = 0; + if (ffParsePropLines(start, "level: ", &temp)) + level = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); + + if (ffParsePropLines(start, "scale: ", &temp)) + scale = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); + + if (level > 0 && scale > 0) + battery->capacity = level * 100 / scale; + } + + if(options->temp) + { + if (ffParsePropLines(start, "temperature: ", &temp)) + battery->temperature = ffStrbufToDouble(&temp); + ffStrbufClear(&temp); + } + + ffParsePropLines(start, "technology: ", &battery->technology); + + return NULL; +} + +const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) +{ + const char* error = parseTermuxApi(options, results); + if (error && parseDumpsys(options, results) == NULL) + return NULL; + return error; +}