#include "displayserver.h"
#include "common/settings.h"
#include "common/processing.h"
#include <math.h>
static bool checkHdrStatus(FFDisplayResult* display)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSettingsGetAndroidProperty("ro.surface_flinger.has_HDR_display", &buffer))
{
if (ffStrbufIgnCaseEqualS(&buffer, "true"))
{
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
if (ffSettingsGetAndroidProperty("persist.sys.hdr_mode", &buffer) &&
ffStrbufToUInt(&buffer, 0) > 0)
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
return true;
}
else
{
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
return true;
}
}
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
return false;
}
static void detectWithDumpsys(FFDisplayServerResult* ds)
{
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if (ffProcessAppendStdOut(&buf, (char* []) {
"/system/bin/dumpsys",
"display",
NULL,
}) != NULL || buf.length == 0)
return;
uint32_t index = 0;
while ((index = ffStrbufNextIndexS(&buf, index, "DisplayDeviceInfo")) < buf.length)
{
index += strlen("DisplayDeviceInfo");
uint32_t nextIndex = ffStrbufNextIndexC(&buf, index, '\n');
buf.chars[nextIndex] = '\0';
const char* info = buf.chars + index;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateA(64);
unsigned width = 0, height = 0, modeId = 0;
double refreshRate = 0;
int res = sscanf(info, "{\"%63[^\"]\":%*s%u x %u, modeId%u", name.chars, &width, &height, &modeId);
if (res >= 3)
{
if (res == 4)
{
++info; while ((info = strchr(info, '{')))
{
++info;
unsigned id;
double fps;
if (sscanf(info, "id=%u, %*s%*s fps=%lf", &id, &fps) >= 2)
{
if (id == modeId)
{
refreshRate = fps;
break;
}
}
else
break;
}
}
ffStrbufRecalculateLength(&name);
FFDisplayResult* display = ffdsAppendDisplay(ds,
(uint32_t)width,
(uint32_t)height,
refreshRate,
0,
0,
0,
0,
0,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0,
0,
0,
"dumpsys"
);
if (display) display->hdrStatus = checkHdrStatus(display);
}
index = nextIndex + 1;
}
}
static bool detectWithGetprop(FFDisplayServerResult* ds)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
ffStrbufContainC(&buffer, ','))
{
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
FFDisplayResult* display = ffdsAppendDisplay(ds,
width,
height,
0,
(uint32_t) (width / scaleFactor + .5),
(uint32_t) (height / scaleFactor + .5),
0,
0,
0,
0,
NULL,
FF_DISPLAY_TYPE_BUILTIN,
false,
0,
0,
0,
"getprop"
);
if (display) display->hdrStatus = checkHdrStatus(display);
return !!display;
}
return false;
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
{
ffStrbufSetStatic(&ds->wmProcessName, "WindowManager");
ffStrbufSetStatic(&ds->wmPrettyName, "Window Manager");
if (!detectWithGetprop(ds))
detectWithDumpsys(ds);
}