Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ jobs:
from PyInstaller.utils.hooks import collect_all;
from openadb.version import ACBRIDGE_APK_FILENAME, RELEASE_EXE_FILENAME;
assert callable(collect_all);
assert ACBRIDGE_APK_FILENAME == 'ACBridge-3.0.1.apk';
assert RELEASE_EXE_FILENAME == 'OpenADB-3.0.1.exe'"
assert ACBRIDGE_APK_FILENAME == 'ACBridge-3.0.2.apk';
assert RELEASE_EXE_FILENAME == 'OpenADB-3.0.2.exe'"

- name: Check repository privacy guardrails
shell: pwsh
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/device-lab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ jobs:
$null -eq $json -or
$json.schema -ne "openadb.device-lab.v1" -or
$json.product.name -ne "OpenADB" -or
$json.product.version -ne "3.0.1" -or
$json.product.version -ne "3.0.2" -or
$json.product.source_commit -ne $expectedSourceCommit -or
[string]::IsNullOrWhiteSpace([string]$json.environment.os) -or
[string]::IsNullOrWhiteSpace([string]$json.environment.release) -or
Expand Down
48 changes: 24 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: OpenADB 3.0.1 release
name: OpenADB 3.0.2 release

on:
push:
tags:
- v3.0.1
- v3.0.2
workflow_dispatch:
inputs:
tag:
description: Release tag; dispatch this workflow from the same tag ref
required: true
default: v3.0.1
default: v3.0.2
type: string
allow_unsigned_stable:
description: Explicitly publish an unsigned stable release (artifact keeps the -unsigned suffix)
Expand All @@ -31,7 +31,7 @@ jobs:
tag: ${{ steps.release-ref.outputs.tag }}
allow_unsigned_stable: ${{ steps.release-ref.outputs.allow_unsigned_stable }}
steps:
- name: Require the immutable 3.0.1 tag
- name: Require the immutable 3.0.2 tag
id: release-ref
shell: pwsh
env:
Expand All @@ -47,8 +47,8 @@ jobs:
'${{ github.ref_name }}'
}

if ($tag -ne 'v3.0.1') {
throw "This release workflow is intentionally restricted to v3.0.1; received '$tag'."
if ($tag -ne 'v3.0.2') {
throw "This release workflow is intentionally restricted to v3.0.2; received '$tag'."
}
if ($env:CURRENT_REF -ne "refs/tags/$tag") {
throw "Run a manual release from the $tag tag ref, not from a branch or a different tag."
Expand Down Expand Up @@ -212,7 +212,7 @@ jobs:
if (@(Compare-Object $requiredTopLevel $actualTopLevel).Count -ne 0) {
throw 'BUILD_STATUS.json has missing or unexpected top-level fields.'
}
if ($status.version -ne '3.0.1') {
if ($status.version -ne '3.0.2') {
throw "Unexpected build version '$($status.version)'."
}
if ($status.signed -isnot [bool]) {
Expand All @@ -236,21 +236,21 @@ jobs:
$bridgeKeys = @($status.acbridge.PSObject.Properties.Name)
if (@(Compare-Object @('package', 'version_name', 'version_code', 'apk_filename') $bridgeKeys).Count -ne 0 -or
$status.acbridge.package -ne 'com.communism420.acbridge' -or
$status.acbridge.version_name -ne '3.0.1' -or
[int]$status.acbridge.version_code -ne 30101 -or
$status.acbridge.apk_filename -ne 'ACBridge-3.0.1.apk') {
$status.acbridge.version_name -ne '3.0.2' -or
[int]$status.acbridge.version_code -ne 30201 -or
$status.acbridge.apk_filename -ne 'ACBridge-3.0.2.apk') {
throw 'BUILD_STATUS.json contains unexpected ACBridge metadata.'
}

$expectedName = if ($status.signed) {
'OpenADB-3.0.1.exe'
'OpenADB-3.0.2.exe'
} else {
'OpenADB-3.0.1-unsigned.exe'
'OpenADB-3.0.2-unsigned.exe'
}
$expectedArtifactName = if ($status.signed) {
'OpenADB-3.0.1-windows-signed'
'OpenADB-3.0.2-windows-signed'
} else {
'OpenADB-3.0.1-windows-unsigned'
'OpenADB-3.0.2-windows-unsigned'
}
if ($env:BUILD_ARTIFACT_NAME -ne $expectedArtifactName -or
$env:BUILD_OUTPUT_FILENAME -ne $expectedName -or
Expand All @@ -261,7 +261,7 @@ jobs:
if ($status.filename -ne $expectedName) {
throw "Build filename '$($status.filename)' does not match its signed status."
}
$executables = @(Get-ChildItem -LiteralPath $release -File -Filter 'OpenADB-3.0.1*.exe')
$executables = @(Get-ChildItem -LiteralPath $release -File -Filter 'OpenADB-3.0.2*.exe')
if ($executables.Count -ne 1 -or $executables[0].Name -ne $expectedName) {
throw 'The build artifact must contain exactly one correctly named OpenADB executable.'
}
Expand Down Expand Up @@ -303,7 +303,7 @@ jobs:
throw "Unsigned build has an unexpected Authenticode state: $($signature.Status)."
}

$apkSource = 'openadb/resources/acbridge/ACBridge-3.0.1.apk'
$apkSource = 'openadb/resources/acbridge/ACBridge-3.0.2.apk'
if (-not (Test-Path -LiteralPath $apkSource -PathType Leaf) -or
(Get-Item -LiteralPath $apkSource).Length -le 0) {
throw 'The versioned ACBridge APK is missing or empty at the release tag.'
Expand All @@ -312,7 +312,7 @@ jobs:

$releaseFiles = @(
$exe.FullName,
(Join-Path $release 'ACBridge-3.0.1.apk'),
(Join-Path $release 'ACBridge-3.0.2.apk'),
$statusPath
)
$newSums = foreach ($file in $releaseFiles) {
Expand Down Expand Up @@ -344,10 +344,10 @@ jobs:
$changelog = Get-Content -LiteralPath 'CHANGELOG_EN.md' -Raw -Encoding utf8
$match = [regex]::Match(
$changelog,
'(?ms)^## \[3\.0\.1\].*?(?=^## \[|\z)'
'(?ms)^## \[3\.0\.2\].*?(?=^## \[|\z)'
)
if (-not $match.Success) {
throw 'CHANGELOG_EN.md does not contain a 3.0.1 release section.'
throw 'CHANGELOG_EN.md does not contain a 3.0.2 release section.'
}
$status = Get-Content -LiteralPath 'release/BUILD_STATUS.json' -Raw -Encoding utf8 |
ConvertFrom-Json
Expand All @@ -360,7 +360,7 @@ jobs:
}

$notes = @"
# OpenADB 3.0.1
# OpenADB 3.0.2

## Artifact status

Expand Down Expand Up @@ -419,11 +419,11 @@ jobs:
}

$title = if ($env:SIGNED -eq 'true') {
'OpenADB 3.0.1'
'OpenADB 3.0.2'
} elseif ($env:STABLE -eq 'true') {
'OpenADB 3.0.1 (explicitly approved unsigned)'
'OpenADB 3.0.2 (explicitly approved unsigned)'
} else {
'OpenADB 3.0.1 unsigned preview'
'OpenADB 3.0.2 unsigned preview'
}
$arguments = @(
'release', 'create', $env:RELEASE_TAG,
Expand All @@ -436,7 +436,7 @@ jobs:
}
$arguments += @(
(Join-Path 'release' $env:EXE_FILENAME),
'release/ACBridge-3.0.1.apk',
'release/ACBridge-3.0.2.apk',
'release/BUILD_STATUS.json',
'release/SHA256SUMS.txt'
)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:
required: false
push:
tags:
- "v3.0.1"
- "v3.0.2"

permissions:
contents: read
Expand All @@ -39,7 +39,7 @@ defaults:
shell: pwsh

env:
OPENADB_VERSION: "3.0.1"
OPENADB_VERSION: "3.0.2"
PLATFORM_TOOLS_VERSION: "37.0.0"
PLATFORM_TOOLS_ARCHIVE: "platform-tools_r37.0.0-win.zip"
PLATFORM_TOOLS_ARCHIVE_SHA1: "f29bfb58d0d6f9a57d7dbcba6cc259f9ca6f58f1"
Expand Down
69 changes: 67 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,74 @@ All notable OpenADB changes made since the start of the local audit and project
redesign are documented in this file.

The format is based on Keep a Changelog. The current public project version is
3.0.1.
3.0.2.

## [3.0.1] — Unreleased
## [3.0.2] — Unreleased

### Fixed

- Replaced the private-file `run-as` P2P bootstrap with a request-scoped
abstract Android control socket reached through a temporary local-only ADB
forward. P2P startup no longer fails on otherwise supported OEM devices
whose `/data` permissions cause Android's `run-as` safety check to reject
the helper before any file bytes are sent.
- ACBridge now reports storage-permission state and the authenticated `READY`
startup acknowledgement through the same bounded control channel. OpenADB
waits for that acknowledgement before opening the LAN data connection.
- Service startup now uses the Android 6–7-compatible path on API 23–25 and a
foreground service on Android 8 and later.
- The LocalSocket read timeout now applies only to the bounded bootstrap. The
established control monitor remains blocking until request-scoped cleanup
closes it, preventing normal SAF waits from being mistaken for disconnects
on Android releases that surface idle LocalSocket timeouts as `IOException`.

### Security and lifecycle

- The bootstrap secret and generated session metadata remain in memory and are
not placed in process arguments or request/status files on the Android
filesystem. ACBridge accepts the forwarded control channel only from the
Android shell or root peer identity.
- Cancellation and cleanup are request-scoped. Success, cancellation, timeout,
and startup failure close the control sockets and remove only the matching
temporary ADB forward, without overriding a more useful primary error.
- OpenADB also recovers the unique matching forward when Platform Tools loses
or returns a malformed creation response, and sends a public-ID cancellation
fallback so closing the tunnel cannot race ahead of Android consuming
`CANCEL`.
- Control messages are size-bounded and deadline-aware; authenticated startup
validation and the existing authenticated P2P data protocol remain in
effect.

### Version

- Updated OpenADB, ACBridge, Windows metadata, build workflows, screenshots,
and active release documentation to version 3.0.2.
- ACBridge 3.0.2 uses `versionCode 30201` under the documented version-code
policy and is released as `ACBridge-3.0.2.apk`.

### Validation

- Added automated regression coverage for the ADB-forwarded control bootstrap,
authenticated startup acknowledgement, cancellation, cleanup, redaction,
control-frame limits, and Android-version-specific service startup.
- A disposable read-only API 36 Android emulator completed a two-session
nested-folder upload: three files, six entries, 1,048,624 bytes, an empty
directory, and every SHA-256 were verified. Emulator NAT required a
test-only ADB forward for the data sockets, so this validates ACBridge,
control, folder, and integrity behavior but not direct-LAN routing or speed.
- The unsigned one-file EXE passed a clean-profile title, bundled Platform
Tools, normal-close, and crash-log smoke test. Thirty-eight isolated test
modules passed cleanly; all 41 assertions in the remaining adaptive-window
module passed, but its local PySide6 offscreen process then exited with a
native Windows heap-corruption code. The packaged EXE did not reproduce that
teardown failure. Windows CI run `29409867004` subsequently passed the full
clean-process matrix on CPython 3.10–3.14, so the native exit remains a
local-host-only observation rather than a reproduced release failure.
- No physical Android device, OEM Android 17 build, removable storage, or
direct-LAN route was available, so physical hardware transfer success
remains to be verified.

## [3.0.1] — 2026-07-13

### Fixed

Expand Down
69 changes: 67 additions & 2 deletions CHANGELOG_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,74 @@ All notable OpenADB changes made since the start of the local audit and project
redesign are documented in this file.

The format is based on Keep a Changelog. The current public project version is
3.0.1.
3.0.2.

## [3.0.1] — Unreleased
## [3.0.2] — Unreleased

### Fixed

- Replaced the private-file `run-as` P2P bootstrap with a request-scoped
abstract Android control socket reached through a temporary local-only ADB
forward. P2P startup no longer fails on otherwise supported OEM devices
whose `/data` permissions cause Android's `run-as` safety check to reject
the helper before any file bytes are sent.
- ACBridge now reports storage-permission state and the authenticated `READY`
startup acknowledgement through the same bounded control channel. OpenADB
waits for that acknowledgement before opening the LAN data connection.
- Service startup now uses the Android 6–7-compatible path on API 23–25 and a
foreground service on Android 8 and later.
- The LocalSocket read timeout now applies only to the bounded bootstrap. The
established control monitor remains blocking until request-scoped cleanup
closes it, preventing normal SAF waits from being mistaken for disconnects
on Android releases that surface idle LocalSocket timeouts as `IOException`.

### Security and lifecycle

- The bootstrap secret and generated session metadata remain in memory and are
not placed in process arguments or request/status files on the Android
filesystem. ACBridge accepts the forwarded control channel only from the
Android shell or root peer identity.
- Cancellation and cleanup are request-scoped. Success, cancellation, timeout,
and startup failure close the control sockets and remove only the matching
temporary ADB forward, without overriding a more useful primary error.
- OpenADB also recovers the unique matching forward when Platform Tools loses
or returns a malformed creation response, and sends a public-ID cancellation
fallback so closing the tunnel cannot race ahead of Android consuming
`CANCEL`.
- Control messages are size-bounded and deadline-aware; authenticated startup
validation and the existing authenticated P2P data protocol remain in
effect.

### Version

- Updated OpenADB, ACBridge, Windows metadata, build workflows, screenshots,
and active release documentation to version 3.0.2.
- ACBridge 3.0.2 uses `versionCode 30201` under the documented version-code
policy and is released as `ACBridge-3.0.2.apk`.

### Validation

- Added automated regression coverage for the ADB-forwarded control bootstrap,
authenticated startup acknowledgement, cancellation, cleanup, redaction,
control-frame limits, and Android-version-specific service startup.
- A disposable read-only API 36 Android emulator completed a two-session
nested-folder upload: three files, six entries, 1,048,624 bytes, an empty
directory, and every SHA-256 were verified. Emulator NAT required a
test-only ADB forward for the data sockets, so this validates ACBridge,
control, folder, and integrity behavior but not direct-LAN routing or speed.
- The unsigned one-file EXE passed a clean-profile title, bundled Platform
Tools, normal-close, and crash-log smoke test. Thirty-eight isolated test
modules passed cleanly; all 41 assertions in the remaining adaptive-window
module passed, but its local PySide6 offscreen process then exited with a
native Windows heap-corruption code. The packaged EXE did not reproduce that
teardown failure. Windows CI run `29409867004` subsequently passed the full
clean-process matrix on CPython 3.10–3.14, so the native exit remains a
local-host-only observation rather than a reproduced release failure.
- No physical Android device, OEM Android 17 build, removable storage, or
direct-LAN route was available, so physical hardware transfer success
remains to be verified.

## [3.0.1] — 2026-07-13

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion GUI_AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Дата аудита: 10 июля 2026 года

Текущая версия: OpenADB 3.0.1
Текущая версия: OpenADB 3.0.2

Среда: Windows, Python 3.14.3, PySide6 6.11.1, экран 1920×1080, системная тёмная тема

Expand Down
2 changes: 1 addition & 1 deletion GUI_REDESIGN_REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Дата: 12 июля 2026 года

Версия отчёта: OpenADB 3.0.1
Версия отчёта: OpenADB 3.0.2

Платформа проверки: Windows, Python 3.14.3, PySide6 6.11.1

Expand Down
Loading
Loading