<feed xmlns='http://www.w3.org/2005/Atom'>
<title>android/scrcpy-android/app/src, branch 0.2</title>
<subtitle>[no description]</subtitle>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/'/>
<entry>
<title>build: verify release inputs</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=0f88f2c1e5e108021ccddeee24f1216107115791'/>
<id>0f88f2c1e5e108021ccddeee24f1216107115791</id>
<content type='text'>
Pin and verify what goes into a release: JitPack confined to the
SPAKE2 module via exclusiveContent, the vendored subtree pulled by
commit SHA instead of a mutable tag, a pinned Docker base digest with
a checksummed cmdline-tools download, and a verifyScrcpyServer task
wired into every assets merge. The expected server checksum can be
overridden with -PscrcpyServerSha256 when the jar is built from
source.

build-apk now requires apksigner and fails unless independent
signature verification succeeds. Split the test image into unit and
e2e targets so JVM-only test runs do not download an emulator. Ship
THIRD_PARTY_NOTICES and the LGPL text for SPAKE2 in the APK. Add
scripts/check as the host quality gate.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pin and verify what goes into a release: JitPack confined to the
SPAKE2 module via exclusiveContent, the vendored subtree pulled by
commit SHA instead of a mutable tag, a pinned Docker base digest with
a checksummed cmdline-tools download, and a verifyScrcpyServer task
wired into every assets merge. The expected server checksum can be
overridden with -PscrcpyServerSha256 when the jar is built from
source.

build-apk now requires apksigner and fails unless independent
signature verification succeeds. Split the test image into unit and
e2e targets so JVM-only test runs do not download an emulator. Ship
THIRD_PARTY_NOTICES and the LGPL text for SPAKE2 in the APK. Add
scripts/check as the host quality gate.
</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>
<entry>
<title>app: clamp forwarded touch pressure to u16</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=431a0e36f42ef3c44de4fd46f304ad2b38e4b3cd'/>
<id>431a0e36f42ef3c44de4fd46f304ad2b38e4b3cd</id>
<content type='text'>
MotionEvent.getPressure() is calibrated around 1.0 but may exceed it
on some digitizers. Masking with 0xffff wrapped hard presses around
to a light touch; clamp instead.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
MotionEvent.getPressure() is calibrated around 1.0 but may exceed it
on some digitizers. Masking with 0xffff wrapped hard presses around
to a light touch; clamp instead.
</pre>
</div>
</content>
</entry>
<entry>
<title>app: guard VideoSink.submit against torn-down codec</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=735ca8b58dc341f4521a162346ba14fe943eb2bb'/>
<id>735ca8b58dc341f4521a162346ba14fe943eb2bb</id>
<content type='text'>
reconfigure() tears the codec down outside the lock, so an in-flight
MediaCodec callback can reach submit() while `codec` is null. The NPE
lands on the callback handler thread, which has no catch and kills
the process. Drop the frame instead, like any back-pressure casualty.

Also rewrite the back-pressure comment: it described a keyframe-aware
drop policy this class cannot implement (the keyframe flag never
reaches it). The real policy protects config frames only.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
reconfigure() tears the codec down outside the lock, so an in-flight
MediaCodec callback can reach submit() while `codec` is null. The NPE
lands on the callback handler thread, which has no catch and kills
the process. Drop the frame instead, like any back-pressure casualty.

Also rewrite the back-pressure comment: it described a keyframe-aware
drop policy this class cannot implement (the keyframe flag never
reaches it). The real policy protects config frames only.
</pre>
</div>
</content>
</entry>
<entry>
<title>scrcpy-android: mirror an Android device over wireless ADB</title>
<updated>2026-06-24T19:14:50+00:00</updated>
<author>
<name>Lena</name>
<email>lena@omega</email>
</author>
<published>2026-01-01T00:00:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.0xlena.dev/android/scrcpy-android/commit/?id=eb0c8951196c637e44daf3c0617b131b997d5d2c'/>
<id>eb0c8951196c637e44daf3c0617b131b997d5d2c</id>
<content type='text'>
Native Java app for Android 12+ that mirrors another Android
device over wireless ADB, forwarding video, audio, touch input,
and clipboard. Bundles a pinned scrcpy-server.jar and the
vendored libadb-android stack. Supports h264/h265/av1 video and
raw/opus audio with in-app codec selection. No NDK, no Kotlin.
Includes JVM unit tests and a Docker-based emulator e2e rig.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Native Java app for Android 12+ that mirrors another Android
device over wireless ADB, forwarding video, audio, touch input,
and clipboard. Bundles a pinned scrcpy-server.jar and the
vendored libadb-android stack. Supports h264/h265/av1 video and
raw/opus audio with in-app codec selection. No NDK, no Kotlin.
Includes JVM unit tests and a Docker-based emulator e2e rig.
</pre>
</div>
</content>
</entry>
</feed>
