Repository navigation
Add live device screen streaming to the Screen Capture window - #224
Conversation
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>
|
/review |
|
ℹ️ Skipped — a harness review for this commit ( 🤖 Helpful? 👍/👎 |
There was a problem hiding this comment.
💡 Harness Review
The streaming pipeline is thoughtfully integrated, but several reachable UI, persistence, and startup edge cases can leave the displayed or saved content inconsistent or prevent streaming.
Reviewed commit 5aced5d
🤖 Helpful? 👍/👎
|
/review |
|
/review |
|
/review |
|
/review |
|
/design-consistency |
IGuscin
left a comment
There was a problem hiding this comment.
Thanks, that's an awesome improvement. Very useful for testing purposes.
Tested the functionality on Samsung Galaxy S23+ Android 13 and Pixel 9 Pro XL Android 17.
Live capture works fine, doesn't lag even on highest available settings, mouse, keyboard input works as expected as well.
Tomas quickly addressed couple small issues I've noticed. The only remaining issue I've seen related to rotation of Unity apps not working reproduces in Android Studio as well, so probably is a generic Unity issue, rather than Logcat.
anjalin14
left a comment
There was a problem hiding this comment.
Thanks for the docs! I've left quite a few suggestions but those are mostly minor nits around conversational tone, formatting, and passive voice fixes. I've also added a couple of comments for clarification. I'm approving now but happy to re-review if you'd like!
| Select **Browse...** to pick a folder. A folder inside the project is stored relative to it, and one outside it is stored as an absolute path. | ||
|
|
||
| The default, `AndroidLogcat/Captures`, is a folder in your project, beside `Assets`. It is outside `Assets`, so captures are never imported and are not part of a build, and it survives deleting `Library`, so captures stay until you delete them. It is not covered by Unity's own `.gitignore`, so add it to yours if you do not want captures in source control. |
There was a problem hiding this comment.
| Select **Browse...** to pick a folder. A folder inside the project is stored relative to it, and one outside it is stored as an absolute path. | |
| The default, `AndroidLogcat/Captures`, is a folder in your project, beside `Assets`. It is outside `Assets`, so captures are never imported and are not part of a build, and it survives deleting `Library`, so captures stay until you delete them. It is not covered by Unity's own `.gitignore`, so add it to yours if you do not want captures in source control. | |
| To choose a folder, select **Browse...**. If the folder is inside the project, Unity stores it as a relative path. If the folder is outside the project, Unity stores it as an absolute path. | |
| The default, `AndroidLogcat/Captures`, is a folder in your project, beside `Assets`. It is outside `Assets`, so Unity doesn't import captures or include them in a build. Deleting the `Library` folder doesn't remove the captures folder. Captures in this folder remain until you delete them. Unity's own `.gitignore` file doesn't cover the captures folder. If you don't want captures in source control, add the captures folder to your own `.gitignore` file. |
|
|
||
| The default, `AndroidLogcat/Captures`, is a folder in your project, beside `Assets`. It is outside `Assets`, so captures are never imported and are not part of a build, and it survives deleting `Library`, so captures stay until you delete them. It is not covered by Unity's own `.gitignore`, so add it to yours if you do not want captures in source control. | ||
|
|
||
| Changing the folder takes effect immediately. Captures already written stay where they are, and the [Capture list](screen-capture-window-reference.md#capture-list) shows what is in the new folder. |
There was a problem hiding this comment.
can you clarify this a bit. Does this mean, if the captures are moved from A to B, captures still remain in folder A and the captures list display only items from folder B?
There was a problem hiding this comment.
Yes, exactly. Existing captures aren't moved: they stay in folder A, and the list shows only what's in B. I reworded the paragraph to say that explicitly, and that you can move old captures (with their .json files) yourself. Fixed in 59f276f.
|
|
||
| The live view mirrors the device's display into the Unity Editor. Unlike a screenshot or a video, there is nothing to save: the view is live and stops when you select something else. | ||
|
|
||
| ## View the screen |
There was a problem hiding this comment.
| ## View the screen | |
| ## View the screen | |
| To view the device screen live: |
There was a problem hiding this comment.
adding a lead line for steps
| | **Vol +** | Sends the Volume Up key. | | ||
| | **Vol -** | Sends the Volume Down key. | | ||
|
|
||
| Below them, **Device Rotation** turns the device's screen: |
There was a problem hiding this comment.
| Below them, **Device Rotation** turns the device's screen: | |
| **Device Rotation** turns the device's screen: |
|
|
||
| On a foldable, **Device Fold** follows: **Fold**, **Unfold**, and **Half** on a device that reports half open as a state of its own, hold the device that way whatever its hinge is doing - which is how the other display is reached without touching the device. **Auto** hands it back to the hinge. The row does not appear for a device that does not fold. | ||
|
|
||
| **Take Screenshot**, at the bottom, captures the device screen and adds it to the [Capture list](#capture-list). The screenshot is taken on the device rather than copied from the stream, so it is full resolution whatever the stream is scaled down to. Ctrl+Shift+S (Cmd+Shift+S on macOS) does the same while this window has focus and the **Live** row is selected - the shortcut follows the button, so it does nothing while a saved capture is on screen. |
There was a problem hiding this comment.
| **Take Screenshot**, at the bottom, captures the device screen and adds it to the [Capture list](#capture-list). The screenshot is taken on the device rather than copied from the stream, so it is full resolution whatever the stream is scaled down to. Ctrl+Shift+S (Cmd+Shift+S on macOS) does the same while this window has focus and the **Live** row is selected - the shortcut follows the button, so it does nothing while a saved capture is on screen. | |
| Under *Device Capture**, **Take Screenshot** captures the device screen and adds it to the [Capture list](#capture-list). The screenshot is taken on the device rather than copied from the stream, so it is full resolution regardless of how the stream is scaled. **Ctrl+Shift+S** (macOS: **Cmd+Shift+S**) does the same while this window has focus and the **Live** row is selected. The shortcut has no effect while a saved capture is on screen. |
There was a problem hiding this comment.
Applied in 59f276f (fixed the missing * in Device Capture, and "while a saved capture is selected").
| @@ -5,10 +5,17 @@ This page explains how to use the [Screen Capture tool](screen-capture.md) to ca | |||
| 1. Open the [Device Screen Capture window](screen-capture-window-reference.md). | |||
| 2. In the [Toolbar](screen-capture-window-reference.md#toolbar), use **Device Selector** to specify to device to take a screenshot of. | |||
There was a problem hiding this comment.
| 2. In the [Toolbar](screen-capture-window-reference.md#toolbar), use **Device Selector** to specify to device to take a screenshot of. | |
| 2. In the [Toolbar](screen-capture-window-reference.md#toolbar), use **Device Selector** to specify the device to take a screenshot of. |
| * [Capture a screenshot](screen-capture-screenshot.md) | ||
| * [Capture a video](screen-capture-video.md) | ||
| * [View the device screen live](screen-capture-live-stream.md) | ||
| * [Stacktace Utility](stacktrace-utility.md) |
There was a problem hiding this comment.
| * [Stacktace Utility](stacktrace-utility.md) | |
| * [Stacktrace Utility](stacktrace-utility.md) |
anjalin14
left a comment
There was a problem hiding this comment.
Thanks for the docs! I've left quite a few suggestions but those are mostly minor nits around conversational tone, formatting, and passive voice fixes. I've also added a couple of comments for clarification. I'm approving now but happy to re-review if you'd like!
|
pls ignore the duplicate comment due to a Github glitch |
…settings.md Co-authored-by: anjalin14 <anjali.nabar@unity3d.com>
…settings.md Co-authored-by: anjalin14 <anjali.nabar@unity3d.com>
…window-reference.md Co-authored-by: anjalin14 <anjali.nabar@unity3d.com>
Address review suggestions on the Screen Capture and Android Logcat Settings pages: tone, passive voice, key formatting, no directional wording, Device Fold table, and correct the stale Library folder note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Will merge, trunk related issues will be addressed separately in #228 |
https://jira.unity3d.com/browse/PLAT-22403
Type of change:
Description
The main logcat window is not affected by this change, only screen capture window is affected
How to test? Go to https://yamato.ds.unity3d.com/project/277/branch/livestream/jobDefinition/.yamato%2Fwrench%2Fpackage-pack-jobs.yml%23package_pack_-_mobile_android-logcat/recent-jobs , take latest artifacts, extract them, and add com.unity.mobile.android-logcat-1.5.0.tgz package to Unity. tgz file will have the necessary jar inside.
https://www.youtube.com/watch?v=YmHoV16Ld8Q
You can now watch the device's screen live in the Screen Capture window, and click, scroll and type into it from the Editor. The window opens from Window > Analysis > Android Screen Capture, so it no longer has to be reached through the Logcat window.
Capturing needs something on the device: External/UnityLogcatServer is a small Gradle project that builds an 18 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. The jar is a build output rather than a committed binary, and a Yamato job builds it before the package is packed — that half is also up on its own as #226, cherry-picked from this branch to make it reviewable.
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, and below them Device Rotation (Auto, 0°, 90°, 180°, 270°) and, on a foldable, Device Fold (Auto, Fold, Half, Unfold) drive the device into a state without touching it. Take Screenshot is there too, so a screenshot is taken from where you are watching, at full device resolution whatever the stream is scaled to.
The window was reorganised around it. Screenshots used to overwrite one file in Temp; they are now kept, listed down the left under a Live toggle button, and each one is saved with a .json details file beside it recording the device, its Android version and the display size at the time. Where they go is a setting — Captures Folder, Library/AndroidLogcat/Screenshots by default.
The list takes a selection of more than one row (Shift and Ctrl click, Ctrl+A), and arrow keys, Home and End move through it. F2 renames, Del deletes, and right-click offers Show in Explorer / Reveal in Finder, Open, Copy To..., Rename, Delete and Select All, with the multi-row entries saying how many they will act on. Double-click opens a capture in whatever the OS associates with it. Ctrl+Shift+S (Cmd+Shift+S on macOS) takes a screenshot while the live view is showing.
A status bar along the bottom says where the last capture was written and what the stream is doing — the device, the display size, what it is scaled to and the frame rate cap. Stream size, JPEG quality and frame rate cap, and the captures folder, are in Preferences > Analysis > Android Logcat Settings, reachable from the window's own toolbar menu.
Improved screenshot window
Settings
Checklist for PR maker
Testing status
Devices:
Testing checklist