From ef82e116ccfe647ccdc5a53c45624696e030e142 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 11:47:30 +0000 Subject: [PATCH 01/10] Phone page: the phone in Android, with Fastboot Studio Companion A new page reads a phone running Android over adb while it is open: model, chip, Android, patch level, slot, battery, kernel and KMI, bootloader state, SELinux and AVB, without root. With the Companion module installed it asks fbs info and fbs modules through su and shows the bootloader's own AVB state (pointing out a hiding module that changed the property), the root manager, storage wear and every conflict between modules; without it the page says what the module adds and links to it. The Companion's backups in /sdcard/FastbootStudio/Backups are listed with their kind, size and date, and one click copies a backup to the Backup page's folder and checks it against SHA256SUMS. Reboot to bootloader, fastbootd or recovery from the header. PhoneReport (Core) parses both reads and is tested against the Companion's own test phone output; FakeAdb plays the module for the screenshot run, which copies and checks a backup and captures the page with and without the module, in Arabic and in the light theme. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_018ZnrQUTw6hd6BgdooEqhkR --- .github/scripts/screenshots.ps1 | 64 ++ BackupUI.cs | 5 +- MainWindow.xaml | 218 ++++++ MainWindow.xaml.cs | 1 + PhoneUI.cs | 531 ++++++++++++++ Properties/Resources.Designer.cs | 676 ++++++++++++++++++ Properties/Resources.ar.resx | 225 ++++++ Properties/Resources.resx | 225 ++++++ README.ar.md | 17 + README.md | 19 + Themes/Styles.xaml | 3 +- UiModels.cs | 84 +++ src/FastbootEnhance.Core/Adb/PhoneReport.cs | 638 +++++++++++++++++ .../FastbootEnhance.Core.csproj | 2 + .../PhoneReportTests.cs | 255 +++++++ tools/FastbootEnhance.FakeAdb/Program.cs | 133 +++- 16 files changed, 3093 insertions(+), 3 deletions(-) create mode 100644 PhoneUI.cs create mode 100644 src/FastbootEnhance.Core/Adb/PhoneReport.cs create mode 100644 tests/FastbootEnhance.Core.Tests/PhoneReportTests.cs diff --git a/.github/scripts/screenshots.ps1 b/.github/scripts/screenshots.ps1 index 485dc6d..c62330b 100644 --- a/.github/scripts/screenshots.ps1 +++ b/.github/scripts/screenshots.ps1 @@ -819,6 +819,54 @@ if (Test-Path $stockBoot) { Write-Host "root: stock boot sent, Magisk image pulled and checked, flashed to boot" } +# ---------------------------------------------------------------- phone +# A phone in Android with Fastboot Studio Companion: read without root, then through su (the +# bootloader's own AVB state wins over the property a hiding module changed). The boot backup +# on the phone is copied and checked against its SHA256SUMS; then the same phone without the +# module offers to get it. +$adbCompanion = Join-Path $appDir 'fake-adb.companion' +Set-Content $adbMode 'android' +Remove-Item $adbCompanion -ErrorAction SilentlyContinue +function Text-Of([string] $id) { return (By-Id $root $id).Current.Name } +function Phone-Buttons([string] $label) { + $cond = New-Object System.Windows.Automation.PropertyCondition($UIA::ControlTypeProperty, $Type::Button) + return @((By-Id $root 'phone_backups').FindAll($Scope::Descendants, $cond) | Where-Object { $_.Current.Name -eq $label -and -not $_.Current.IsOffscreen }) +} +Go 'phone_tab' | Out-Null +Wait-For { Shown $root 'phone_companion_version' } 60 "the Companion's report" | Out-Null +$phoneBackups = Wait-For { By-Id $root 'phone_backups' } 10 "the phone's backups" +Wait-For { (Rows $phoneBackups).Count -eq 3 } 20 "three backups on the phone" | Out-Null +if ((Text-Of 'phone_companion_version') -notmatch '2\.4\.0') { Fail "the Companion version is '$(Text-Of 'phone_companion_version')'" } +if ((Text-Of 'phone_avb') -ne 'AVB orange') { Fail "AVB shows '$(Text-Of 'phone_avb')', not the bootloader's orange" } +if ((Text-Of 'phone_soc') -ne 'Qualcomm') { Fail "the chip maker shows '$(Text-Of 'phone_soc')'" } +Start-Sleep -Milliseconds 600 +Save-Window ('{0:D2}a-phone' -f ($i - 1)) + +$copyLabel = 'Copy and verify' +$copyButtons = Wait-For { $b = Phone-Buttons $copyLabel; if ($b.Count -eq 3) { $b } } 10 "a copy button on each backup" +$copyButtons[2].GetCurrentPattern([System.Windows.Automation.InvokePattern]::Pattern).Invoke() +$copied = Join-Path $saveRoot 'Backups\Sample_A64_FBE0SAMPLE02_20260830-091233' +Wait-For { (Phone-Buttons $copyLabel).Count -eq 2 -and (Phone-Buttons 'Open').Count -eq 1 } 60 "the boot backup to be copied and checked" | Out-Null +if (-not (Test-Path (Join-Path $copied 'SHA256SUMS'))) { Fail "the backup was not copied to $copied" } +Push-Location $copied +foreach ($line in Get-Content 'SHA256SUMS') { + $hash, $file = $line -split ' ', 2 + if ((Get-FileHash $file -Algorithm SHA256).Hash.ToLower() -ne $hash) { Pop-Location; Fail "$file does not match SHA256SUMS" } +} +Pop-Location +if (@(Get-Content $fakeAdbLog | Where-Object { $_ -match 'pull \| -a \| /sdcard/FastbootStudio/Backups/' }).Count -ne 1) { Fail "the backup was not pulled exactly once" } +Start-Sleep -Milliseconds 600 +Save-Window ('{0:D2}b-phone-copied' -f ($i - 1)) + +Set-Content $adbCompanion 'missing' +Press 'phone_read_again' +Wait-For { Shown $root 'phone_companion_get' } 40 "the page to offer the Companion" | Out-Null +if ($null -ne (Shown $root 'phone_companion_version')) { Fail "the Companion still shows after it was removed" } +Start-Sleep -Milliseconds 600 +Save-Window ('{0:D2}c-phone-no-companion' -f ($i - 1)) +Remove-Item $adbMode, $adbCompanion -ErrorAction SilentlyContinue +Write-Host "phone: read with the Companion (AVB from the bootloader, 3 conflicts), boot backup copied and checked, then without it" + # ---------------------------------------------------------------- terminal # A command typed in the Terminal runs with the bundled fastboot and shows its output; one # that erases a boot-chain partition asks for the name first, and answering No runs nothing. @@ -915,6 +963,15 @@ if ($Arabic) { Remove-Item $adbMode -ErrorAction SilentlyContinue } + # The Phone page, right to left, with the Companion's report. + Set-Content $adbMode 'android' + Go 'phone_tab' | Out-Null + Wait-For { Shown $root 'phone_companion_version' } 60 "the Companion's report (Arabic)" | Out-Null + Wait-For { (Rows (By-Id $root 'phone_backups')).Count -eq 3 } 20 "the phone's backups (Arabic)" | Out-Null + Start-Sleep -Milliseconds 600 + Save-Window 'ar-11-phone' + Remove-Item $adbMode -ErrorAction SilentlyContinue + if (Test-Path $superPart) { Go 'images_tab' | Out-Null Open-Image $superPart @@ -972,6 +1029,13 @@ Start-Sleep -Seconds 3 Save-Window 'light-02-device' Go 'flash_tab' | Out-Null Save-Window 'light-03-flash' +Set-Content $adbMode 'android' +Go 'phone_tab' | Out-Null +Wait-For { Shown $root 'phone_companion_version' } 60 "the Companion's report (light)" | Out-Null +Wait-For { (Rows (By-Id $root 'phone_backups')).Count -eq 3 } 20 "the phone's backups (light)" | Out-Null +Start-Sleep -Milliseconds 600 +Save-Window 'light-06-phone' +Remove-Item $adbMode -ErrorAction SilentlyContinue Go 'terminal_tab' | Out-Null Terminal-Run 'fastboot devices' Wait-For { (Terminal-Output) -match 'FBE0SAMPLE01' } 30 "fastboot devices in the terminal (light)" | Out-Null diff --git a/BackupUI.cs b/BackupUI.cs index ae70eb1..3cebb4c 100644 --- a/BackupUI.cs +++ b/BackupUI.cs @@ -37,6 +37,9 @@ static class BackupUI static string saveRoot = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Fastboot Studio"); + /// The folder backups are saved to; the Phone page copies the Companion's backups there too. + public static string SaveRoot => saveRoot; + static string lastOutputFolder; static volatile bool busy; @@ -1047,7 +1050,7 @@ static void pullSelected() }); } - static void openInExplorer(string folder) + internal static void openInExplorer(string folder) { try { diff --git a/MainWindow.xaml b/MainWindow.xaml index ebd8396..ec2a699 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -220,6 +220,224 @@ + + + + + + + + + + + + + + + +