Files
fastfetch/src/detection/displayserver/displayserver_android.c
T

210 lines
7.3 KiB
C
Raw Normal View History

2023-07-19 13:59:40 +08:00
#include "displayserver.h"
#include "common/settings.h"
2023-07-19 13:59:40 +08:00
#include "common/processing.h"
2025-09-01 09:59:24 +08:00
#include "linux/displayserver_linux.h"
2023-07-19 13:59:40 +08:00
2024-07-11 14:05:34 +08:00
#include <math.h>
2026-03-29 09:28:49 +08:00
static bool checkHdrStatus(FFDisplayResult* display) {
2025-03-26 16:42:39 +08:00
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
2026-03-29 09:28:49 +08:00
if (ffSettingsGetAndroidProperty("ro.surface_flinger.has_HDR_display", &buffer)) {
if (ffStrbufIgnCaseEqualS(&buffer, "true")) {
2025-03-26 16:42:39 +08:00
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
if (ffSettingsGetAndroidProperty("persist.sys.hdr_mode", &buffer) &&
2026-03-29 09:28:49 +08:00
ffStrbufToUInt(&buffer, 0) > 0) {
2025-03-26 16:42:39 +08:00
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
2026-03-29 09:28:49 +08:00
}
2025-03-26 16:42:39 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else {
2025-03-26 16:42:39 +08:00
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
return true;
}
}
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
return false;
}
2026-03-29 09:28:49 +08:00
static void detectWithDumpsys(FFDisplayServerResult* ds) {
2023-07-19 13:59:40 +08:00
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
2026-03-29 09:28:49 +08:00
if (ffProcessAppendStdOut(&buf, (char*[]) {
"/system/bin/dumpsys",
"display",
2026-07-10 18:08:04 +08:00
nullptr,
}) != nullptr ||
2026-03-29 09:28:49 +08:00
buf.length == 0) {
2023-07-19 13:59:40 +08:00
return; // Only works in `adb shell`, or when rooted
2026-03-29 09:28:49 +08:00
}
2023-07-19 13:59:40 +08:00
uint32_t index = 0;
2026-03-29 09:28:49 +08:00
while ((index = ffStrbufNextIndexS(&buf, index, "DisplayDeviceInfo")) < buf.length) {
2023-07-19 13:59:40 +08:00
index += strlen("DisplayDeviceInfo");
uint32_t nextIndex = ffStrbufNextIndexC(&buf, index, '\n');
buf.chars[nextIndex] = '\0';
const char* info = buf.chars + index;
// {"Builtin display": uniqueId="local:4630947134992368259", 1440 x 3200, modeId 2, defaultModeId 1, supportedModes [{id=1, width=1440, height=3200, fps=60.000004, alternativeRefreshRates=[24.000002, 30.000002, 40.0, 120.00001, 120.00001, 120.00001, 120.00001, 120.00001]},
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(64);
unsigned width = 0, height = 0, modeId = 0;
double refreshRate = 0;
// {"Builtin display": uniqueId="local:4630947134992368259", 1440 x 3200, modeId 2
int res = sscanf(info, "{\"%63[^\"]\":%*s%u x %u, modeId%u", name.chars, &width, &height, &modeId);
2026-03-29 09:28:49 +08:00
if (res >= 3) {
if (res == 4) {
2023-07-19 13:59:40 +08:00
++info; // skip first '{'
2026-03-29 09:28:49 +08:00
while ((info = strchr(info, '{'))) {
2023-07-19 13:59:40 +08:00
++info;
unsigned id;
double fps;
// id=1, width=1440, height=3200, fps=60.000004,
2026-03-29 09:28:49 +08:00
if (sscanf(info, "id=%u, %*s%*s fps=%lf", &id, &fps) >= 2) {
if (id == modeId) {
2023-07-19 13:59:40 +08:00
refreshRate = fps;
break;
}
2026-03-29 09:28:49 +08:00
} else {
2023-07-19 13:59:40 +08:00
break;
2026-03-29 09:28:49 +08:00
}
2023-07-19 13:59:40 +08:00
}
}
ffStrbufRecalculateLength(&name);
2025-03-26 16:42:39 +08:00
FFDisplayResult* display = ffdsAppendDisplay(ds,
2026-03-29 09:28:49 +08:00
(uint32_t) width,
(uint32_t) height,
2023-07-19 13:59:40 +08:00
refreshRate,
0,
2026-03-29 09:28:49 +08:00
0,
0,
2024-11-20 16:13:38 +08:00
0,
0,
2023-07-19 13:59:40 +08:00
&name,
FF_DISPLAY_TYPE_UNKNOWN,
false,
2024-07-11 14:05:34 +08:00
0,
0,
0,
2026-03-29 09:28:49 +08:00
"dumpsys");
if (display) {
display->hdrStatus = checkHdrStatus(display);
}
2023-07-19 13:59:40 +08:00
}
2023-07-19 13:59:40 +08:00
index = nextIndex + 1;
}
}
2026-03-29 09:28:49 +08:00
static bool detectWithGetprop(FFDisplayServerResult* ds) {
// Only for MiUI
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
2023-10-21 15:44:38 +08:00
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
2026-03-29 09:28:49 +08:00
ffStrbufContainC(&buffer, ',')) {
2024-07-22 19:24:29 +08:00
// 1440,3200,560 => width,height,densityDpi
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
2024-07-11 14:05:34 +08:00
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t dpi = (uint32_t) ffStrbufToUInt(&buffer, 0) * 96 / 160;
2025-03-26 16:42:39 +08:00
FFDisplayResult* display = ffdsAppendDisplay(ds,
2026-03-29 09:28:49 +08:00
width,
height,
0,
dpi,
2026-03-29 09:28:49 +08:00
0,
0,
2024-11-20 16:13:38 +08:00
0,
0,
2026-07-10 18:08:04 +08:00
nullptr,
FF_DISPLAY_TYPE_BUILTIN,
false,
2024-07-11 14:05:34 +08:00
0,
2024-07-22 19:24:29 +08:00
0,
0,
2026-03-29 09:28:49 +08:00
"getprop");
if (display) {
display->hdrStatus = checkHdrStatus(display);
}
2025-03-26 16:42:39 +08:00
return !!display;
}
return false;
}
2026-03-29 09:28:49 +08:00
static bool detectDE(FFDisplayServerResult* ds) {
2025-11-24 15:01:18 +08:00
if (ffSettingsGetAndroidProperty("ro.vivo.os.build.display.id", &ds->dePrettyName)) // OriginOS 6
{
ffStrbufAppendC(&ds->dePrettyName, ' ');
ffSettingsGetAndroidProperty("ro.vivo.product.version", &ds->dePrettyName); // PD2505D_xxx
return true;
}
if (ffSettingsGetAndroidProperty("ro.build.version.magic", &ds->dePrettyName) ||
2026-03-29 09:28:49 +08:00
ffSettingsGetAndroidProperty("ro.build.version.emui", &ds->dePrettyName)) {
2025-11-24 15:01:18 +08:00
ffStrbufReplaceAllC(&ds->dePrettyName, '_', ' ');
return true;
}
2026-03-29 09:28:49 +08:00
if (ffSettingsGetAndroidProperty("ro.mi.os.version.name", &ds->dePrettyName)) {
2025-11-24 15:01:18 +08:00
// MiUI like
ffStrbufClear(&ds->dePrettyName);
ffSettingsGetAndroidProperty("ro.build.version.incremental", &ds->dePrettyName); // Detail version number
2026-03-29 09:28:49 +08:00
if (ffStrbufStartsWithS(&ds->dePrettyName, "OS")) {
2025-11-24 15:01:18 +08:00
ds->dePrettyName.chars[0] = 'S';
ds->dePrettyName.chars[1] = ' ';
ffStrbufPrependS(&ds->dePrettyName, "HyperO");
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&ds->dePrettyName, "V")) {
2025-11-24 15:01:18 +08:00
ds->dePrettyName.chars[0] = ' ';
ffStrbufPrependS(&ds->dePrettyName, "MiUI");
2026-03-29 09:28:49 +08:00
} else {
2025-11-24 15:01:18 +08:00
ffStrbufSetStatic(&ds->dePrettyName, "MiUI");
2026-03-29 09:28:49 +08:00
}
2025-11-24 15:01:18 +08:00
return true;
}
2026-03-29 09:28:49 +08:00
if (ffSettingsGetAndroidProperty("ro.build.version.oplusrom", &ds->dePrettyName)) {
if (ffStrbufStartsWithS(&ds->dePrettyName, "V")) {
2025-11-24 15:01:18 +08:00
ffStrbufSubstrAfter(&ds->dePrettyName, 0);
2026-03-29 09:28:49 +08:00
}
2025-11-24 15:01:18 +08:00
ffStrbufPrependS(&ds->dePrettyName, "ColorOS");
return true;
}
2026-03-29 09:28:49 +08:00
if (ffSettingsGetAndroidProperty("ro.oxygen.version", &ds->dePrettyName)) {
2025-11-24 15:01:18 +08:00
ffStrbufPrependS(&ds->dePrettyName, "OxygenOS");
return true;
}
2026-03-29 09:28:49 +08:00
if (ffSettingsGetAndroidProperty("ro.build.display.id", &ds->dePrettyName)) {
if (ffStrbufStartsWithS(&ds->dePrettyName, "RedMagicOS")) {
ffStrbufInsertNC(&ds->dePrettyName, strlen("RedMagicOS"), 1, ' ');
2026-03-29 09:28:49 +08:00
}
// Google Pixel uses native Android
2025-11-24 15:01:18 +08:00
return true;
}
return false;
}
2026-03-29 09:28:49 +08:00
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) {
2025-09-01 09:59:24 +08:00
const char* error = ffdsConnectXcbRandr(ds);
2026-03-29 09:28:49 +08:00
if (error) {
2025-09-01 09:59:24 +08:00
error = ffdsConnectXrandr(ds);
2026-03-29 09:28:49 +08:00
}
if (!error) {
2025-09-01 09:59:24 +08:00
ffdsDetectWMDE(ds);
return;
}
// https://source.android.com/docs/core/graphics/surfaceflinger-windowmanager
ffStrbufSetStatic(&ds->wmProcessName, "system_server");
ffStrbufSetStatic(&ds->wmPrettyName, "WindowManager"); // A system service managed by system_server
2025-09-01 09:59:24 +08:00
ffStrbufSetStatic(&ds->wmProtocolName, FF_WM_PROTOCOL_SURFACEFLINGER);
2026-03-29 09:28:49 +08:00
if (!detectWithGetprop(ds)) {
detectWithDumpsys(ds);
2026-03-29 09:28:49 +08:00
}
2025-11-24 15:01:18 +08:00
detectDE(ds);
}