blob: 472f5a60a6ee1da43bb2f9756ca5a901051c3267 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package adb
import (
"fmt"
"regexp"
"strconv"
"android.googlesource.com/platform/tools/gpu/client/android"
"android.googlesource.com/platform/tools/gpu/framework/log"
)
// Event types
const (
EV_ABS = 3
EV_SYN = 0
)
// Event codes
const (
ABS_MT_TRACKING_ID = 57
ABS_MT_POSITION_X = 53
ABS_MT_POSITION_Y = 54
ABS_MT_PRESSURE = 58
ABS_MT_TOUCH_MAJOR = 48
SYN_REPORT = 0
)
// KeyEvent simulates a key-event on the device.
func (b *binding) KeyEvent(ctx log.Context, key android.KeyCode) error {
return b.Shell("input", "keyevent", strconv.Itoa(int(key))).Run(ctx)
}
// SendEvent simulates low-level user-input to the device.
func (b *binding) SendEvent(ctx log.Context, deviceId, eventType, eventCode, value int) error {
args := fmt.Sprintf("/dev/input/event%v %v %v %v", deviceId, eventType, eventCode, value)
return b.Shell("sendevent", args).Run(ctx)
}
// SendTouch simulates touch-screen press or release.
func (b *binding) SendTouch(ctx log.Context, deviceId, x, y int, pressed bool) {
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_TRACKING_ID, 0)
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_POSITION_X, x)
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_POSITION_Y, y)
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_PRESSURE, 50)
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_TOUCH_MAJOR, 5)
b.SendEvent(ctx, deviceId, EV_SYN, SYN_REPORT, 0)
if !pressed {
b.SendEvent(ctx, deviceId, EV_ABS, ABS_MT_TRACKING_ID, -1)
b.SendEvent(ctx, deviceId, EV_SYN, SYN_REPORT, 0)
}
}
func atoi(s string) int {
v, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
return v
}
// GetTouchDimensions returns the resolution of the touch sensor.
// This may be different to the dimensions of the LCD screen.
func (b *binding) GetTouchDimensions(ctx log.Context) (deviceId, minX, maxX, minY, maxY int, ok bool) {
for i := 0; i < 10; i++ {
device := "/dev/input/event" + strconv.Itoa(i)
if info, err := b.Shell("getevent", "-lp", device).Call(ctx); err == nil {
reX := regexp.MustCompile("ABS_MT_POSITION_X.* min ([0-9]+), max ([0-9]+),")
reY := regexp.MustCompile("ABS_MT_POSITION_Y.* min ([0-9]+), max ([0-9]+),")
matchX := reX.FindStringSubmatch(info)
matchY := reY.FindStringSubmatch(info)
if matchX != nil && matchY != nil {
return i, atoi(matchX[1]), atoi(matchX[2]), atoi(matchY[1]), atoi(matchY[2]), true
}
}
}
return 0, 0, 0, 0, 0, false
}
// GetScreenDimensions returns the resolution of the display.
func (b *binding) GetScreenDimensions(ctx log.Context) (orientation, width, height int, ok bool) {
if info, err := b.Shell("dumpsys", "display").Call(ctx); err == nil {
re := regexp.MustCompile("mDefaultViewport.*orientation=([0-9]+).*deviceWidth=([0-9]+).*deviceHeight=([0-9]+)")
if match := re.FindStringSubmatch(info); match != nil {
return atoi(match[1]), atoi(match[2]), atoi(match[3]), true
}
}
return 0, 0, 0, false
}