mirror of
https://github.com/taigrr/adb.git
synced 2026-04-02 02:58:42 -07:00
123 lines
2.8 KiB
Go
123 lines
2.8 KiB
Go
package adb
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
// CaptureSequence allows you to record a series of taps and swipes on the screen to replay later
|
|
//
|
|
// This function is useful if you need to run an obscure shell command or if
|
|
// you require functionality not provided by the exposed functions here.
|
|
// Instead of using Shell, please consider submitting a PR with the functionality
|
|
// you require.
|
|
|
|
type SequenceSleep struct {
|
|
Duration time.Duration
|
|
}
|
|
|
|
func (s SequenceSleep) Play(d Device, ctx context.Context) error {
|
|
// TODO check if context is expired
|
|
time.Sleep(s.Duration)
|
|
return nil
|
|
}
|
|
|
|
func (s SequenceSleep) Length() time.Duration {
|
|
return s.Duration
|
|
}
|
|
|
|
type SequenceTap struct {
|
|
X int
|
|
Y int
|
|
}
|
|
|
|
func (s SequenceTap) Play(d Device, ctx context.Context) error {
|
|
return d.Tap(ctx, s.X, s.Y)
|
|
}
|
|
|
|
func (s SequenceTap) Length() time.Duration {
|
|
return 0
|
|
}
|
|
|
|
type SequenceSwipe struct {
|
|
X1 int
|
|
Y1 int
|
|
X2 int
|
|
Y2 int
|
|
Duration time.Duration
|
|
}
|
|
|
|
func (s SequenceSwipe) Play(d Device, ctx context.Context) error {
|
|
return d.Swipe(ctx, s.X1, s.Y1, s.X2, s.Y2, s.Duration)
|
|
}
|
|
|
|
func (s SequenceSwipe) Length() time.Duration {
|
|
return s.Duration
|
|
}
|
|
|
|
type Input interface {
|
|
Play(d Device, ctx context.Context) error
|
|
Length() time.Duration
|
|
}
|
|
|
|
type TapSequence struct {
|
|
Events []Input
|
|
}
|
|
|
|
// ShortenSleep allows you to shorten all the sleep times between tap and swipe events.
|
|
//
|
|
// Provide a scalar value to divide the sleeps by. Providing `2` will halve all
|
|
// sleep durations in the TapSequence. Swipe durations and tap durations are
|
|
// unaffected.
|
|
|
|
func (t TapSequence) ShortenSleep(scalar int) TapSequence {
|
|
seq := []Input{}
|
|
for _, s := range t.Events {
|
|
switch y := s.(type) {
|
|
case SequenceSleep:
|
|
y.Duration = y.Duration / time.Duration(scalar)
|
|
seq = append(seq, y)
|
|
default:
|
|
seq = append(seq, s)
|
|
}
|
|
}
|
|
t.Events = seq
|
|
return t
|
|
}
|
|
|
|
// GetLength returns the length of all Input events inside of a given TapSequence
|
|
//
|
|
// This function is useful for devermining how long a context timeout should
|
|
// last when calling ReplayTapSequence
|
|
func (t TapSequence) GetLength() time.Duration {
|
|
duration := time.Duration(0)
|
|
for _, x := range t.Events {
|
|
duration += x.Length()
|
|
}
|
|
return duration
|
|
}
|
|
|
|
func (d Device) ReplayTapSequence(ctx context.Context, t TapSequence) error {
|
|
for _, e := range t.Events {
|
|
err := e.Play(d, ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d Device) CaptureSequence(ctx context.Context) (t TapSequence, err error) {
|
|
// this command will never finish, and always returns error code 130 if successful
|
|
stdout, _, errCode, err := execute(ctx, []string{"shell", "getevent", "-tl"})
|
|
if errCode != 130 {
|
|
log.Printf("Expected error code 130, but got \n", errCode)
|
|
}
|
|
if stdout == "" {
|
|
return TapSequence{}, ErrStdoutEmpty
|
|
}
|
|
|
|
return TapSequence{}, nil
|
|
}
|