<feed xmlns='http://www.w3.org/2005/Atom'>
<title>android/scrcpy-android/app/src/main/java/invalid/lena, branch 0.5</title>
<subtitle>[no description]</subtitle>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/'/>
<entry>
<title>app: refine physical-device interface</title>
<updated>2026-08-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-08-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=3037f9f8fdcc6cdadfe94ba248d10e647578cf53'/>
<id>3037f9f8fdcc6cdadfe94ba248d10e647578cf53</id>
<content type='text'>
Use target-safe capture defaults and remove redundant navigation and
frame-rate controls.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Use target-safe capture defaults and remove redundant navigation and
frame-rate controls.
</pre>
</div>
</content>
</entry>
<entry>
<title>video: reset stalled encoder generations</title>
<updated>2026-08-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-08-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=70290eb3d79a5347cdc114daf6ce0b1b2e86528a'/>
<id>70290eb3d79a5347cdc114daf6ce0b1b2e86528a</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>audio: harden Opus playback</title>
<updated>2026-08-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-08-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=75b1a5569bf9048acefa49f2921b2653a828d545'/>
<id>75b1a5569bf9048acefa49f2921b2653a828d545</id>
<content type='text'>
Preserve decoder timing and keep blocking speaker writes off codec
callbacks. Playback failures no longer take down video or control.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Preserve decoder timing and keep blocking speaker writes off codec
callbacks. Playback failures no longer take down video or control.
</pre>
</div>
</content>
</entry>
<entry>
<title>app: harden mirroring lifecycle and state</title>
<updated>2026-08-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-08-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=852a8a00273c9128efeed0217a8e5d3fcd8bf780'/>
<id>852a8a00273c9128efeed0217a8e5d3fcd8bf780</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>adb: reduce and harden wireless transport</title>
<updated>2026-08-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-08-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=f379b93d52bf0dbd3816ec3f64d165314771d2a6'/>
<id>f379b93d52bf0dbd3816ec3f64d165314771d2a6</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>app: enter the device address as one host:port field</title>
<updated>2026-07-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-07-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=30ee8be82e44d1a8250d1f6e27e71f7d5f24aec5'/>
<id>30ee8be82e44d1a8250d1f6e27e71f7d5f24aec5</id>
<content type='text'>
The form asked for a host, a pairing port and a connection port as three
separate fields. Nothing on screen says which port is which, and the two
are only distinguishable if the reader already knows how adb pair works
on Android 11+.

Take the connection endpoint the way the target prints it, as a single
"ip:port" string copied off the Wireless debugging screen, and leave the
pairing dialog with just its port and code. Devices.parseAddress() does
the split and rejects anything malformed rather than guessing: an
unbracketed IPv6 literal would otherwise be split at the wrong colon.

Reported on the F-Droid submission (fdroiddata!41394).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The form asked for a host, a pairing port and a connection port as three
separate fields. Nothing on screen says which port is which, and the two
are only distinguishable if the reader already knows how adb pair works
on Android 11+.

Take the connection endpoint the way the target prints it, as a single
"ip:port" string copied off the Wireless debugging screen, and leave the
pairing dialog with just its port and code. Devices.parseAddress() does
the split and rejects anything malformed rather than guessing: an
unbracketed IPv6 literal would otherwise be split at the wrong colon.

Reported on the F-Droid submission (fdroiddata!41394).
</pre>
</div>
</content>
</entry>
<entry>
<title>app: pad Main and Settings for system bar insets</title>
<updated>2026-07-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-07-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=c03f0464c1f834c2f4d8642cbfad322033d368b7'/>
<id>c03f0464c1f834c2f4d8642cbfad322033d368b7</id>
<content type='text'>
targetSdk 35 makes every window edge-to-edge on Android 15. Neither
activity handled insets, so Main drew its header under the status bar
and the Settings ScrollView started at window y=0: the framework action
bar covered its first 80dp and the navigation bar covered the last rows.

Pad both roots by the system bar insets. Main adds the IME inset as
well, since an edge-to-edge window is not resized when the keyboard
opens. Settings drops the framework action bar and draws its own title
like Main already does, which removes the action-bar-versus-inset
interaction entirely.

Reported on the F-Droid submission (fdroiddata!41394).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
targetSdk 35 makes every window edge-to-edge on Android 15. Neither
activity handled insets, so Main drew its header under the status bar
and the Settings ScrollView started at window y=0: the framework action
bar covered its first 80dp and the navigation bar covered the last rows.

Pad both roots by the system bar insets. Main adds the IME inset as
well, since an edge-to-edge window is not resized when the keyboard
opens. Settings drops the framework action bar and draws its own title
like Main already does, which removes the action-bar-versus-inset
interaction entirely.

Reported on the F-Droid submission (fdroiddata!41394).
</pre>
</div>
</content>
</entry>
<entry>
<title>app: fix session lifecycle, teardown, and opus playback</title>
<updated>2026-07-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-07-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=ff7acf898b48359275a5b09b82ed926a945233f8'/>
<id>ff7acf898b48359275a5b09b82ed926a945233f8</id>
<content type='text'>
Opus playback never worked: feed() called dequeueInputBuffer() on a
codec in async-callback mode, which always throws, so every packet
was silently dropped. Feed input through the async callback with a
bounded pending queue instead.

Make bring-up transactional: roll back partially opened streams and
the server shell on failure, join reader threads on stop, and close
the owning ADB streams before releasing sinks. Replace the
openAbstract watchdog thread with a real timeout in the vendored
AdbConnection.open(), which also removes the half-open stream from
the lookup table on failure.

Harden the activity: release owned Surfaces, gate callbacks on a
destroyed flag and a session generation, serialize reconnect, and
handle target replacement via singleTask + onNewIntent. Propagate
device-list write failures instead of swallowing them, bound the
clipboard payload and the video pending queue against hostile
peers, and discard incomplete recordings instead of keeping corrupt
files.

Use the mediaPlayback foreground-service type; Android 15 stops
dataSync services after six hours. Drop the unused
ACCESS_NETWORK_STATE permission.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Opus playback never worked: feed() called dequeueInputBuffer() on a
codec in async-callback mode, which always throws, so every packet
was silently dropped. Feed input through the async callback with a
bounded pending queue instead.

Make bring-up transactional: roll back partially opened streams and
the server shell on failure, join reader threads on stop, and close
the owning ADB streams before releasing sinks. Replace the
openAbstract watchdog thread with a real timeout in the vendored
AdbConnection.open(), which also removes the half-open stream from
the lookup table on failure.

Harden the activity: release owned Surfaces, gate callbacks on a
destroyed flag and a session generation, serialize reconnect, and
handle target replacement via singleTask + onNewIntent. Propagate
device-list write failures instead of swallowing them, bound the
clipboard payload and the video pending queue against hostile
peers, and discard incomplete recordings instead of keeping corrupt
files.

Use the mediaPlayback foreground-service type; Android 15 stops
dataSync services after six hours. Drop the unused
ACCESS_NETWORK_STATE permission.
</pre>
</div>
</content>
</entry>
<entry>
<title>treewide: correct stale comments</title>
<updated>2026-07-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-07-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=9f832c148fdd3d9d3e4673e89d2d052c2bcd1efa'/>
<id>9f832c148fdd3d9d3e4673e89d2d052c2bcd1efa</id>
<content type='text'>
- MuxRecorder claimed minSdk 35; it is 31.
- Adb claimed API 34 is the current Android max, next to
  compileSdk 35.
- Server claimed the openAbstract budget is wall-clock bounded below
  the e2e deadline; the deadline is per stream, so the worst case is
  not. Describe what actually holds instead.
- Pixhash contradicted itself about java.desktop availability.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- MuxRecorder claimed minSdk 35; it is 31.
- Adb claimed API 34 is the current Android max, next to
  compileSdk 35.
- Server claimed the openAbstract budget is wall-clock bounded below
  the e2e deadline; the deadline is per stream, so the worst case is
  not. Describe what actually holds instead.
- Pixhash contradicted itself about java.desktop availability.
</pre>
</div>
</content>
</entry>
<entry>
<title>app: report whether a recording was actually written</title>
<updated>2026-07-01T00:00:00+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-07-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=3cc5eff7d8d4b9a33633b99e2a82d3df8cdfd4d6'/>
<id>3cc5eff7d8d4b9a33633b99e2a82d3df8cdfd4d6</id>
<content type='text'>
MuxRecorder had a Listener interface that nothing implemented; every
callback fired into a no-op. Delete it. stop() now returns whether a
keyframe ever landed and the muxer ran, so Mirror can stop claiming
"recording saved" when no file was written.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
MuxRecorder had a Listener interface that nothing implemented; every
callback fired into a no-op. Delete it. stop() now returns whether a
keyframe ever landed and the muxer ran, so Mirror can stop claiming
"recording saved" when no file was written.
</pre>
</div>
</content>
</entry>
</feed>
