ituoke/internal/device/touch_test.go

121 lines
3.2 KiB
Go

package device
import (
"bytes"
"encoding/binary"
"io"
"net"
"testing"
"time"
)
func TestTouchPacket(t *testing.T) {
req := TouchRequest{DeviceID: "phone", Action: 0, X: 123, Y: 456, Width: 576, Height: 1280}
b := encodeTouch(req)
want := []byte{2, 0, 255, 255, 255, 255, 255, 255, 255, 254, 0, 0, 0, 123, 0, 0, 1, 200, 2, 64, 5, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0}
if !bytes.Equal(b, want) {
t.Fatalf("unexpected touch packet %x", b)
}
for _, action := range []int{1, 3} {
req.Action = action
if binary.BigEndian.Uint16(encodeTouch(req)[22:24]) != 0 {
t.Fatal("release pressure is nonzero")
}
}
}
func TestTouchIsWrittenBeforeRelease(t *testing.T) {
writer, reader := net.Pipe()
defer writer.Close()
defer reader.Close()
st := &previewStream{running: true, serial: "phone", controlConn: writer}
s := &Service{stream: st}
received := make(chan []byte, 4)
go func() {
for {
b := make([]byte, 32)
if _, err := io.ReadFull(reader, b); err != nil {
return
}
received <- b
}
}()
req := TouchRequest{DeviceID: "phone", Action: 0, X: 1, Y: 2, Width: 576, Height: 1280}
for _, action := range []int{0, 2, 1} {
req.Action = action
if err := s.Touch(req); err != nil {
t.Fatal(err)
}
select {
case packet := <-received:
if int(packet[1]) != action {
t.Fatal("touch events reordered")
}
case <-time.After(time.Second):
t.Fatal("touch was buffered until release")
}
}
if st.touchDown {
t.Fatal("pointer stuck after release")
}
req.Action = 2
if err := s.Touch(req); err != nil {
t.Fatal(err)
}
select {
case <-received:
t.Fatal("move injected without down")
default:
}
req.Action = 0
req.DeviceID = "other"
if err := s.Touch(req); err == nil {
t.Fatal("input reached a different device")
}
}
func TestScreenOffRestoresDisplayOnStop(t *testing.T) {
writer, reader := net.Pipe()
defer reader.Close()
st := &previewStream{running: true, serial: "phone", controlConn: writer}
s := &Service{stream: st}
packets := make(chan []byte, 1)
go func() { data, _ := io.ReadAll(reader); packets <- data }()
if err := s.SetScreenOff("other", true); err == nil {
t.Fatal("screen power reached a different device")
}
if err := s.SetScreenOff("phone", true); err != nil {
t.Fatal(err)
}
if err := s.SetScreenOff("phone", true); err != nil {
t.Fatal(err)
}
s.StopPreviewStream()
select {
case data := <-packets:
if !bytes.Equal(data, []byte{10, 0, 10, 1}) {
t.Fatalf("expected scrcpy display off followed by restore, got %x", data)
}
case <-time.After(time.Second):
t.Fatal("screen restore was not sent before disconnect")
}
if st.screenOff {
t.Fatal("screen-off state leaked into next connection")
}
if err := s.SetScreenOff("phone", true); err == nil {
t.Fatal("screen power accepted after stream stopped")
}
}
func TestScreenPowerFailureDoesNotCommitState(t *testing.T) {
writer, reader := net.Pipe()
reader.Close()
defer writer.Close()
st := &previewStream{running: true, serial: "phone", controlConn: writer}
if err := (&Service{stream: st}).SetScreenOff("phone", true); err == nil {
t.Fatal("closed control channel was accepted")
}
if st.screenOff {
t.Fatal("failed update was reported as applied")
}
}