Repository navigation
feat: debug HTTP server on port 8085, LAN clients only (#96) - #97
Conversation
- DebugServer: a plain ServerSocket on its own thread, always on for the process, started by the activity. GET only (405 otherwise), one request per connection, 3 s socket timeouts, two workers and a short queue; extra connections are closed. A port that cannot be bound is retried every 10 s and reported in the JSON. - Only clients on the local network are answered: loopback, 10/8, 172.16/12, 192.168/16, link-local (169.254/16, fe80::/10), IPv6 fc00::/7; others get 403. - / is a static page that fetches /stats.json every 1.5 s and renders it. /stats.json: app version and git hash, device, SoC, Android, screen, the device addresses as http://<ip>:8085/ (no 127/8, no 169.254/16), mode, the single-view status or every cell with its corner text, in/lost fps, paused and audio. The state is read on the UI thread; if it does not answer within 1 s the JSON says "ui_thread": "not responding" (useful for the ANR in #76). /log: the last 500 lines of the app's own log (logcat without READ_LOGS). - Logins and passwords never leave the device: URLs and log lines go through the same redaction as the log (#55), plus Authorization headers. - NetInfo: the device addresses and the local-client test; #87 will use it for the U cell hint. - README (EN/RU/ZH): the debug page and a security note.
Seen on the box: an XM slot showed user=admin, only the password was masked.
|
/review |
Code Review by Qodo
1.
|
| c.put("url", DebugServer.redact(mHosts[i])); | ||
| c.put("transport", mTransports[i] != null ? mTransports[i].name() : null); | ||
| TextView v = quadStats[i]; | ||
| c.put("text", v != null ? v.getText().toString() : null); | ||
| c.put("in_fps", cell.inFps()); | ||
| c.put("lost_fps", cell.lostFps()); | ||
| c.put("paused", cell.isPaused()); | ||
| c.put("audio", i == quadAudio); |
There was a problem hiding this comment.
3. Decoder health details are missing 📎 Requirement gap ◔ Observability
debugState() exposes each multi-view cell's text, input and lost fps, paused state, and audio flag, but it does not provide full-rate or key-frame status or decoder-overload data. Both the HTML page and /stats.json consume this same cell data, so those required diagnostics are absent for every multi-view response.
Agent Prompt
## Issue description
The debug snapshot omits the required full-rate or key-frame status and decoder-overload information for multi-view cells.
## Fix Focus Areas
- android/app/src/main/java/com/openipc/decoder/Decoder.java[1007-1029]
- android/app/src/main/java/com/openipc/decoder/QuadCell.java[255-293]
## Recommended Fix
Add explicit per-cell fields for output/full-rate or key-frame status and decoder overload, sourcing them from the decoder state and frame-processing metrics. Include the fields in the JSON snapshot so the existing HTML renderer displays them automatically.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
…data, U view, write deadline - IPv6 site-local (fec0::/10) is no longer a local client: isSiteLocalAddress() counts for IPv4 only. - /log is served from LogBuffer, a ring of the last 500 redacted lines fed by a logcat reader that follows the app's own log for the life of the process. - Each cell reports behind_s (seconds in a row the decoder made it lose frames), with overload_after_s for the threshold (#83). Full rate / key frames comes with #86. - In the U view the JSON has a "udp" object instead of the last single-view state. - A request has a 5 s deadline, writing included: a client that stops reading has its socket closed and cannot hold a worker.
|
All five Qodo findings are fixed in f853086:
Device check of f853086 on the AG-216, 8 cameras: |
|
Qodo re-review of f853086: 1, 4 and 5 resolved. The two remaining items are decided as follows:
|
Understood. The current review status is:
Because the PR is already merged, no further change is required here. |
…data, U view, write deadline - IPv6 site-local (fec0::/10) is no longer a local client: isSiteLocalAddress() counts for IPv4 only. - /log is served from LogBuffer, a ring of the last 500 redacted lines fed by a logcat reader that follows the app's own log for the life of the process. - Each cell reports behind_s (seconds in a row the decoder made it lose frames), with overload_after_s for the threshold (#83). Full rate / key frames comes with #86. - In the U view the JSON has a "udp" object instead of the last single-view state. - A request has a 5 s deadline, writing included: a client that stops reading has its socket closed and cannot hold a worker.
feat: debug HTTP server on port 8085, LAN clients only (#96)
Closes #96.
Always-on read-only HTTP server on port 8085:
/page refreshing itself every 1.5 s,/stats.jsonthe same as JSON,/logthe last 500 lines of the app's log;Authorizationheaders;"ui_thread": "not responding"(ANR on AG-216: RenderThread blocked in eglSwapBuffers with 8 multi-view SurfaceViews #76).NetInfo.addresses()(IPv4, no 127/8, no 169.254/16) is shared with #87.Not in this PR: the
http://<ip>:8085/line in the on-screen debug text. The D button comes with #86; the line goes there once #86 is merged.Device check (AG-216)
curl http://<box>:8085/stats.jsonfrom the LAN: cells with text and fps while 8 cameras play/refreshes in a browser;/logshows the app's lines, no passwordsmode: paused)Checked on AG-216 with build 1565dce (CI): 8 cameras in multi-view, all cells in
/stats.jsonwith text and fps;/200,POST405, unknown path 404;/log500 lines with no login, password or Authorization value. Found and fixed on the device:user=adminin an XM URL was shown (only the password was masked). App in background →mode: paused, back →multi-view. Two device addresses are listed (172.17.32.144 and 172.17.32.115).Build.HARDWAREreportssun50iw9p1(Allwinner H616) on this "AG-216".The decoding impact was not measured separately; the corner fps looked the same with the page open.