Conversation
|
/review |
|
/review |
|
/review |
There was a problem hiding this comment.
💡 Harness Review
The live-stream integration is generally coherent, but concurrent startup and pending-screenshot handling contain reachable lifecycle races, and the protocol documentation does not match the wire format.
Reviewed commit 094a5fa
🤖 Helpful? 👍/👎
|
/review |
|
/review |
| // The list draws itself and the splitter, and hands back what is left. | ||
| var imageRect = m_ScreenshotList.DoGUI(rc); | ||
|
|
||
| if (m_ScreenshotList.LiveSelected) |
There was a problem hiding this comment.
When Live is selected, Capture remains enabled. Capture completion updates SelectedImagePath, but m_LiveSelected remains true, so this branch continues rendering the stream and the newly captured screenshot is not displayed as documented. This is especially visible on a fresh project, where the empty list automatically selects Live. Clear the live selection/stop streaming when capture starts or select the completed screenshot afterward.
🤖 Helpful? 👍/👎
|
/review |
| // belongs to the Layout Viewer as much as to this window. | ||
| else if (!m_ScreenshotList.DoPreviewGUI(imageRect)) | ||
| { | ||
| var message = m_DeviceSelection.SelectedDevice == null |
There was a problem hiding this comment.
This no-device message is unreachable because OnGUI bypasses DoPreviewGUI whenever SelectedDevice is null. Consequently, disconnecting the last device hides the entire device-independent screenshot list, preventing users from viewing, exporting, renaming, or deleting saved captures. Continue rendering the screenshot list without a device and gate only capture/live-stream actions.
🤖 Helpful? 👍/👎
There was a problem hiding this comment.
Confirmed — by removing the device null check from OnGUI() and moving device guarding to Mode.Video and device-specific actions (like capture and live streaming), DoScreenshotGUI() now renders regardless of whether a device is connected. Saved screenshots remain accessible in the list, and the fallback message in DoScreenshotGUI is now reachable when no device is selected.
🤖 Helpful? 👍/👎
| var process = new System.Diagnostics.Process(); | ||
| var si = process.StartInfo; | ||
| si.WorkingDirectory = projectDirectory; | ||
| si.FileName = windows ? Path.Combine(projectDirectory, "gradlew.bat") : "sh"; |
There was a problem hiding this comment.
On Windows this assigns a .bat file directly to ProcessStartInfo.FileName while UseShellExecute is false. That path uses CreateProcess, which cannot execute batch files directly, so the offered “Build the server jar” action fails with a Win32Exception. Launch the wrapper through cmd.exe /c on Windows.
🤖 Helpful? 👍/👎
There was a problem hiding this comment.
@u-pr from what I see, there's no exception it runs fine
There was a problem hiding this comment.
Could it be that RunGradle hasn't actually been executed on Windows in your test? A few reasons why it might appear to run fine without showing an exception:
- The server jar already exists: If
com.unity.mobile.android-logcat/External~/unity-logcat-server.jaris already present on disk, live streaming connects directly through ADB andRunGradleis never invoked. - Platform: If tested on macOS or Linux,
windowsisfalse, so it executessh gradlew ..., which works as expected. - Handled in
try/catch: InAndroidLogcatUtilities.cs,process.Start()is wrapped in atry/catchblock that catchesExceptionand logsDebug.LogError($"Failed to run Gradle in '{projectDirectory}'.\n{ex.Message}")while returningfalse, rather than bubbling up as an unhandled exception.
When RunGradle actually runs on Windows, UseShellExecute = false (which is necessary to redirect standard I/O) causes .NET to invoke the Win32 CreateProcess API directly. CreateProcess only executes binaries and cannot launch .bat or .cmd files directly, throwing a Win32Exception (%1 is not a valid Win32 application / error 193) on process.Start().
To execute the batch wrapper on Windows with UseShellExecute = false, you can route it through cmd.exe /c:
si.FileName = windows ? "cmd.exe" : "sh";
si.Arguments = windows ? $"/c gradlew.bat {task}" : $"gradlew {task}";(Since si.WorkingDirectory is already set to projectDirectory, cmd.exe will find gradlew.bat there.)
🤖 Helpful? 👍/👎
|
/review |
|
|
||
| try | ||
| { | ||
| File.Copy(from, to, true); |
There was a problem hiding this comment.
Save As can silently overwrite an unrelated JSON file. For example, saving a captured screenshot as settings.png in a folder already containing settings.json reaches this call with overwrite: true; the file picker only confirms overwriting the PNG. Move has the same issue because it deletes the destination sidecar first. Check for a destination-sidecar collision and prompt/refuse before modifying it.
🤖 Helpful? 👍/👎
A small Java server, built with Gradle into a dex jar and pushed to the device, that mirrors a display into an ImageReader, encodes each frame as JPEG and writes it to an abstract unix socket. It also reads control messages back up the same socket and injects touch, scroll, key and text events. The jar is a build output and is not committed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The window now lists saved screenshots beside a Live row that mirrors the device. Selecting Live starts the server on the device, shows its frames, and forwards touch, scroll, keyboard and text back to it. Along with it: a shared zoom and pan viewer for the live view and screenshot previews, a details file written beside each capture, a stats column, device rotation, and settings for the stream's size, quality and frame rate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Integration tests covering the stream end to end: frames arriving, injected touch, scroll, keys and text taking effect on the device, streaming a device that was asleep, and an unknown display id. Edit mode coverage for the details file written beside a screenshot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The jar the live stream pushes to the device is a build output and is not committed, so a clone has none. A build_server_jar job produces it and the pack job now depends on it, which is also what puts it in the tarball the test jobs install. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fc65cd1 to
5aced5d
Compare
Type of change:
Description
The main logcat window is not affected by this change, only screen capture window is affected
Video
You can now watch the device's screen live in the Screen Capture window, and click, scroll and type into it from the Editor.
Also, it's not accessible via Window->Analysis->Android Screen Capture
Capturing needs something on the device: External/UnityLogcatServer is a small Gradle project that builds a 17 KB jar, run through app_process as the shell user. It mirrors a display into an ImageReader, JPEG-encodes each frame and writes it over an abstract socket that adb forward exposes. Frames are only produced when the screen changes, so an idle device costs almost nothing.
Input travels back up the same socket: touch, scroll wheel, keys (through the device's own keyboard layout), and Ctrl/Cmd + A, C, V for select-all/copy/paste on the device. Back / Home / Overview buttons sit beside the image, which is the only way in on gesture-navigation devices.
The window was reorganised around it. Screenshots used to overwrite one file in Temp; they're now kept in Library/AndroidLogcat/Screenshots and listed down the left, with the live view as the first row — arrow keys to cycle, F2 rename, Del delete, right-click for Show In Explorer / Open / Save As, Reconnect on the Live row, Ctrl+Shift+S to capture. The window also opens from Window > Analysis > Android Screen Capture. Stream size, JPEG quality and frame rate cap are in Preferences > Analysis > Android Logcat Settings.
Improved screenshot window
Settings
Checklist for PR maker
Testing status
Devices:
Testing checklist