File size: 3,630 Bytes
eae424a
 
 
 
 
 
 
da5fb15
 
 
 
 
 
 
 
 
 
eae424a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da5fb15
eae424a
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
param(
    [Parameter(Mandatory = $true)]
    [string]$OutputDir
)

$ErrorActionPreference = "Stop"

function Relative-Path([string]$Base, [string]$Path) {
    $basePath = [System.IO.Path]::GetFullPath($Base).TrimEnd([char[]]@('\', '/'))
    $fullPath = [System.IO.Path]::GetFullPath($Path)
    $prefix = $basePath + [System.IO.Path]::DirectorySeparatorChar
    if (-not $fullPath.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)) {
        throw "$fullPath is not inside $basePath"
    }
    $fullPath.Substring($prefix.Length)
}

$adbCandidates = @()
if ($env:LOCALAPPDATA) {
    $adbCandidates += Join-Path $env:LOCALAPPDATA "Android\Sdk\platform-tools\adb.exe"
}
if ($env:ANDROID_HOME) {
    $adbCandidates += Join-Path $env:ANDROID_HOME "platform-tools\adb.exe"
}
$adbCandidates = @($adbCandidates | Where-Object { Test-Path -LiteralPath $_ })

if ($adbCandidates.Count -eq 0) {
    throw "adb.exe was not found under LOCALAPPDATA or ANDROID_HOME"
}
$adb = $adbCandidates[0]

$devices = @(& $adb devices | Select-Object -Skip 1 | Where-Object { $_ -match "\tdevice$" })
if ($devices.Count -ne 1) {
    throw "Expected exactly one authorized device; found $($devices.Count). Check 'adb devices'."
}

$destination = [System.IO.Path]::GetFullPath($OutputDir)
if (Test-Path -LiteralPath $destination) {
    if (@(Get-ChildItem -LiteralPath $destination -Force).Count -ne 0) {
        throw "Refusing to merge a recovery pull into non-empty directory: $destination"
    }
} else {
    New-Item -ItemType Directory -Path $destination | Out-Null
}

$runtimeDir = Join-Path $destination "runtime"
$captureDir = Join-Path $destination "captures"
New-Item -ItemType Directory -Path $runtimeDir | Out-Null
New-Item -ItemType Directory -Path $captureDir | Out-Null

$runtimeRemote = "/data/local/tmp/dinovision"
$capturesRemote = "/sdcard/Android/data/rust.dinovision_xr/files/captures"

# adb pull is read-only on the headset. Pull the whole runtime directory first
# so unknown historical files are preserved rather than guessed at by name.
$runtimePresent = $false
& $adb shell "test -d $runtimeRemote"
if ($LASTEXITCODE -eq 0) {
    $runtimePresent = $true
    & $adb pull "$runtimeRemote/." $runtimeDir
    if ($LASTEXITCODE -ne 0) {
        throw "Failed to pull $runtimeRemote"
    }
}

$capturesPresent = $false
& $adb shell "test -d $capturesRemote"
if ($LASTEXITCODE -eq 0) {
    $capturesPresent = $true
    & $adb pull "$capturesRemote/." $captureDir
    if ($LASTEXITCODE -ne 0) {
        throw "Failed to pull $capturesRemote"
    }
}

$metadata = [ordered]@{
    schema_version = 1
    pulled_utc = [DateTime]::UtcNow.ToString("o")
    device = (& $adb get-serialno).Trim()
    product = (& $adb shell getprop ro.product.name).Trim()
    model = (& $adb shell getprop ro.product.model).Trim()
    build_fingerprint = (& $adb shell getprop ro.build.fingerprint).Trim()
    runtime_directory_present = $runtimePresent
    capture_directory_present = $capturesPresent
    files = @(
        Get-ChildItem -LiteralPath $destination -File -Recurse | ForEach-Object {
            [ordered]@{
                path = (Relative-Path $destination $_.FullName).Replace("\", "/")
                bytes = $_.Length
                sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
            }
        }
    )
}

$manifestPath = Join-Path $destination "recovery_manifest.json"
$metadata | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $manifestPath -Encoding utf8
Write-Host "Recovered $($metadata.files.Count) files to $destination"
Write-Host "Manifest: $manifestPath"