fix(adb): keep a bare numeric wm density as the physical density (#4074)
Older Android builds print `wm density` as a bare number. The parser's documentation named that form, but only the labeled `Physical density:` and `Override density:` lines were matched, so a bare `420` left `physical_density` null in successful display Evidence with no limitation saying the declaration was unread (#3942). The parser now reads the first bare numeric line as the physical density when no labeled physical declaration is present; a labeled declaration still wins so a mixed dump cannot downgrade the value. Override density and physical size are unchanged. Validation: parser unit tests for the labeled, bare, CRLF, mixed and unrecognized forms, plus a provider-level regression through the inspect_adb_display operation; two of them fail on main and pass here. The issue's three CLI controls through `rea inspect-adb-display` against a stub adb return physical density 420 for the bare form and keep the labeled and override controls. Typecheck, lint and module boundaries pass. Closes #3942
This commit is contained in:
1 parent
e0b989cc0a
commit
bef3fbbc6e
3 files changed
+75
-3
No files matched your search
@@ -1280,6 +1280,26 @@ it("inspects the display and window focus", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
// Older builds print `wm density` as a bare number; the display projection
|
||||
// must keep it as the physical density (morluto/rea#3942).
|
||||
it("keeps a bare numeric wm density as the physical density", async () => {
|
||||
const { binary } = await writeAdbStub(
|
||||
shellStub({
|
||||
"wm:size": "Physical size: 1080x2340\n",
|
||||
"wm:density": "420\n",
|
||||
}),
|
||||
);
|
||||
const display = await evidenceResult(providerOver(binary), {
|
||||
operation: "inspect_adb_display",
|
||||
input: { serial: "emulator-5554" },
|
||||
});
|
||||
expect(display).toMatchObject({
|
||||
physical_size: { width: 1080, height: 2340 },
|
||||
physical_density: 420,
|
||||
override_density: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("reads Android 16 focus declarations from displays when windows omits them", async () => {
|
||||
const { binary } = await writeAdbStub(
|
||||
shellStub({
|
||||
|
||||
@@ -1,6 +1,49 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { parseAmStartOutput } from "./AdbShellOutput.js";
|
||||
import { parseAmStartOutput, parseWmDensityOutput } from "./AdbShellOutput.js";
|
||||
|
||||
describe("parseWmDensityOutput", () => {
|
||||
it("reads labeled physical and override densities", () => {
|
||||
expect(
|
||||
parseWmDensityOutput("Physical density: 420\nOverride density: 480\n"),
|
||||
).toEqual({ physical: 420, override: 480 });
|
||||
expect(parseWmDensityOutput("Physical density: 420\n")).toEqual({
|
||||
physical: 420,
|
||||
override: null,
|
||||
});
|
||||
});
|
||||
|
||||
// Older builds print the physical density as a bare number
|
||||
// (morluto/rea#3942); it must not be lost as an unread declaration.
|
||||
it("reads a bare numeric density as the physical density", () => {
|
||||
expect(parseWmDensityOutput("420\n")).toEqual({
|
||||
physical: 420,
|
||||
override: null,
|
||||
});
|
||||
expect(parseWmDensityOutput("420\r\n")).toEqual({
|
||||
physical: 420,
|
||||
override: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("prefers a labeled physical density over a bare number", () => {
|
||||
expect(parseWmDensityOutput("560\nPhysical density: 420\n")).toEqual({
|
||||
physical: 420,
|
||||
override: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("reports no density for unrecognized output", () => {
|
||||
expect(parseWmDensityOutput("")).toEqual({
|
||||
physical: null,
|
||||
override: null,
|
||||
});
|
||||
expect(parseWmDensityOutput("420dpi\n")).toEqual({
|
||||
physical: null,
|
||||
override: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const starting =
|
||||
"Starting: Intent { act=android.intent.action.MAIN cmp=com.example/.Main }";
|
||||
|
||||
@@ -125,6 +125,7 @@ const SIZE_PAIR = /^Physical size:\s+(\d+)x(\d+)$/u;
|
||||
const SIZE_OVERRIDE = /^Override size:\s+(\d+)x(\d+)$/u;
|
||||
const DENSITY_PHYSICAL = /^Physical density:\s+(\d+)$/u;
|
||||
const DENSITY_OVERRIDE = /^Override density:\s+(\d+)$/u;
|
||||
const DENSITY_BARE = /^(\d+)$/u;
|
||||
|
||||
/** Parse `wm size` output into physical and optional override sizes. */
|
||||
export const parseWmSizeOutput = (
|
||||
@@ -153,7 +154,12 @@ export const parseWmSizeOutput = (
|
||||
return { physical, override };
|
||||
};
|
||||
|
||||
/** Parse `wm density` output. Older builds print a bare number. */
|
||||
/**
|
||||
* Parse `wm density` output. Current builds print labeled physical and
|
||||
* optional override lines; older builds print the physical density as a
|
||||
* bare number on its own line (morluto/rea#3942). A labeled declaration
|
||||
* wins over a bare one so a mixed dump cannot downgrade the physical value.
|
||||
*/
|
||||
export const parseWmDensityOutput = (
|
||||
stdout: string,
|
||||
): {
|
||||
@@ -162,14 +168,17 @@ export const parseWmDensityOutput = (
|
||||
} => {
|
||||
let physical = null;
|
||||
let override = null;
|
||||
let bare = null;
|
||||
for (const line of stdout.split(/\r?\n/u)) {
|
||||
const trimmed = line.trim();
|
||||
const physicalMatch = DENSITY_PHYSICAL.exec(trimmed);
|
||||
if (physicalMatch !== null) physical = Number(physicalMatch[1]!);
|
||||
const overrideMatch = DENSITY_OVERRIDE.exec(trimmed);
|
||||
if (overrideMatch !== null) override = Number(overrideMatch[1]!);
|
||||
const bareMatch = DENSITY_BARE.exec(trimmed);
|
||||
if (bareMatch !== null && bare === null) bare = Number(bareMatch[1]!);
|
||||
}
|
||||
return { physical, override };
|
||||
return { physical: physical ?? bare, override };
|
||||
};
|
||||
|
||||
/** Parse focus declarations from `dumpsys window windows` or `displays`. */
|
||||
|
||||
Reference in new issue
Block a user