Add atomic composition controls and representative stages
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
param([Parameter(Mandatory)][int[]]$Contacts, [int]$Port=8554)
|
||||
$ErrorActionPreference='Stop'
|
||||
if ($Contacts.Count -eq 0 -or $Contacts.Count % 4 -ne 0) { throw 'Contacts must contain repeated x,y,id,pressure quadruples.' }
|
||||
[AppContext]::SetSwitch('System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport', $true)
|
||||
$discovery=Get-ChildItem -LiteralPath (Join-Path $env:LOCALAPPDATA 'Temp/avd/running') -Filter 'pid_*.ini' | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
$tokenLine=Get-Content -LiteralPath $discovery.FullName | Where-Object { $_ -match '^grpc.token=' } | Select-Object -First 1
|
||||
if (!$tokenLine) { throw 'Authenticated emulator discovery is required; tokens are never logged.' }
|
||||
function Varint([int]$Value) {
|
||||
[uint32]$number=$Value; $bytes=[Collections.Generic.List[byte]]::new()
|
||||
while ($number -ge 128) { $bytes.Add([byte](($number -band 127) -bor 128)); $number=$number -shr 7 }
|
||||
$bytes.Add([byte]$number); return ,$bytes.ToArray()
|
||||
}
|
||||
$message=[Collections.Generic.List[byte]]::new()
|
||||
for ($offset=0; $offset -lt $Contacts.Count; $offset+=4) {
|
||||
$touch=[Collections.Generic.List[byte]]::new()
|
||||
for ($field=0; $field -lt 4; $field++) { $touch.Add([byte](8*($field+1))); $touch.AddRange([byte[]](Varint $Contacts[$offset+$field])) }
|
||||
$message.Add(10); $message.AddRange([byte[]](Varint $touch.Count)); $message.AddRange($touch.ToArray())
|
||||
}
|
||||
$frame=[byte[]]::new($message.Count+5); $frame[1]=($message.Count -shr 24) -band 255; $frame[2]=($message.Count -shr 16) -band 255
|
||||
$frame[3]=($message.Count -shr 8) -band 255; $frame[4]=$message.Count -band 255; $message.ToArray().CopyTo($frame,5)
|
||||
$client=[Net.Http.HttpClient]::new(); $request=[Net.Http.HttpRequestMessage]::new([Net.Http.HttpMethod]::Post,"http://127.0.0.1:$Port/android.emulation.control.EmulatorController/sendTouch")
|
||||
$request.Version=[Version]::new(2,0); $request.VersionPolicy=[Net.Http.HttpVersionPolicy]::RequestVersionExact
|
||||
$request.Headers.Add('TE','trailers'); $request.Headers.Authorization=[Net.Http.Headers.AuthenticationHeaderValue]::new('Bearer',$tokenLine.Substring('grpc.token='.Length))
|
||||
$request.Content=[Net.Http.ByteArrayContent]::new($frame); $request.Content.Headers.ContentType=[Net.Http.Headers.MediaTypeHeaderValue]::new('application/grpc')
|
||||
try {
|
||||
$response=$client.SendAsync($request).GetAwaiter().GetResult(); $response.EnsureSuccessStatusCode() | Out-Null
|
||||
$status=if ($response.TrailingHeaders.Contains('grpc-status')) { ($response.TrailingHeaders.GetValues('grpc-status') -join '') } else { '0' }
|
||||
if ($status -ne '0') { throw "Emulator sendTouch grpc-status=$status" }
|
||||
} finally { $request.Dispose(); $client.Dispose() }
|
||||
Reference in New Issue
Block a user