diff --git a/hrp/pkg/uixt/action.go b/hrp/pkg/uixt/action.go index 45ead572..246c0920 100644 --- a/hrp/pkg/uixt/action.go +++ b/hrp/pkg/uixt/action.go @@ -529,10 +529,11 @@ func (dExt *DriverExt) ParseActionOptions(options ...ActionOption) []ActionOptio func (dExt *DriverExt) GenAbsScope(x1, y1, x2, y2 float64) AbsScope { // convert relative scope to absolute scope - absX1 := int(x1 * float64(dExt.WindowSize.Width)) - absY1 := int(y1 * float64(dExt.WindowSize.Height)) - absX2 := int(x2 * float64(dExt.WindowSize.Width)) - absY2 := int(y2 * float64(dExt.WindowSize.Height)) + windowSize, _ := dExt.Driver.WindowSize() + absX1 := int(x1 * float64(windowSize.Width)) + absY1 := int(y1 * float64(windowSize.Height)) + absX2 := int(x2 * float64(windowSize.Width)) + absY2 := int(y2 * float64(windowSize.Height)) return AbsScope{absX1, absY1, absX2, absY2} } diff --git a/hrp/pkg/uixt/android_adb_driver.go b/hrp/pkg/uixt/android_adb_driver.go index 243828a0..2968fe06 100644 --- a/hrp/pkg/uixt/android_adb_driver.go +++ b/hrp/pkg/uixt/android_adb_driver.go @@ -70,7 +70,7 @@ func (ad *adbDriver) BatteryInfo() (batteryInfo BatteryInfo, err error) { return } -func (ad *adbDriver) WindowSize() (size Size, err error) { +func (ad *adbDriver) getWindowSize() (size Size, err error) { // adb shell wm size output, err := ad.adbClient.RunShellCommand("wm", "size") if err != nil { @@ -99,6 +99,21 @@ func (ad *adbDriver) WindowSize() (size Size, err error) { return Size{Width: width, Height: height}, nil } } + err = errors.New("physical window size not found by adb") + return +} + +func (ad *adbDriver) WindowSize() (size Size, err error) { + if ad.windowSize != nil { + size = *ad.windowSize + } else { + size, err = ad.getWindowSize() + if err != nil { + return + } + ad.windowSize = &size + } + orientation, err := ad.Orientation() if err != nil { log.Warn().Err(err).Msgf("window size get orientation failed, use default orientation") @@ -107,7 +122,6 @@ func (ad *adbDriver) WindowSize() (size Size, err error) { if orientation != OrientationPortrait { size.Width, size.Height = size.Height, size.Width } - err = errors.New("physical window size not found by adb") return } diff --git a/hrp/pkg/uixt/android_uia2_driver.go b/hrp/pkg/uixt/android_uia2_driver.go index f38d8c3c..7632af6d 100644 --- a/hrp/pkg/uixt/android_uia2_driver.go +++ b/hrp/pkg/uixt/android_uia2_driver.go @@ -222,15 +222,22 @@ func (ud *uiaDriver) BatteryInfo() (batteryInfo BatteryInfo, err error) { func (ud *uiaDriver) WindowSize() (size Size, err error) { // register(getHandler, new GetDeviceSize("/wd/hub/session/:sessionId/window/:windowHandle/size")) - var rawResp rawResponse - if rawResp, err = ud.httpGET("/session", ud.sessionId, "window/:windowHandle/size"); err != nil { - return Size{}, errors.Wrap(err, "get window size failed with uiautomator2") + if ud.windowSize != nil { + size = *ud.windowSize + } else { + var rawResp rawResponse + if rawResp, err = ud.httpGET("/session", ud.sessionId, "window/:windowHandle/size"); err != nil { + return Size{}, errors.Wrap(err, "get window size failed with uiautomator2") + } + reply := new(struct{ Value struct{ Size } }) + if err = json.Unmarshal(rawResp, reply); err != nil { + return Size{}, err + } + size = reply.Value.Size + ud.windowSize = &size } - reply := new(struct{ Value struct{ Size } }) - if err = json.Unmarshal(rawResp, reply); err != nil { - return Size{}, err - } - size = reply.Value.Size + + // check orientation orientation, err := ud.Orientation() if err != nil { log.Warn().Err(err).Msgf("window size get orientation failed, use default orientation") diff --git a/hrp/pkg/uixt/client.go b/hrp/pkg/uixt/client.go index 03abb469..632761f7 100644 --- a/hrp/pkg/uixt/client.go +++ b/hrp/pkg/uixt/client.go @@ -16,8 +16,6 @@ import ( ) type DriverSession struct { - // cache device window size - windowSize Size // cache uia2/wda request and response requests []*DriverResult // cache session screenshot ocr results, key is image path, value is ScreenResult @@ -71,7 +69,11 @@ type Driver struct { urlPrefix *url.URL sessionId string client *http.Client - scale float64 + + // cache to avoid repeated query + scale float64 + windowSize *Size + // cache session data session *DriverSession } diff --git a/hrp/pkg/uixt/ext.go b/hrp/pkg/uixt/ext.go index d906225c..e6646631 100644 --- a/hrp/pkg/uixt/ext.go +++ b/hrp/pkg/uixt/ext.go @@ -25,8 +25,6 @@ type DriverExt struct { Driver WebDriver ImageService IImageService // used to extract image data - WindowSize Size - // funplugin plugin funplugin.IPlugin @@ -52,11 +50,6 @@ func newDriverExt(device Device, driver WebDriver, options ...DriverOption) (dEx signal.Notify(dExt.interruptSignal, syscall.SIGTERM, syscall.SIGINT) dExt.doneMjpegStream = make(chan bool, 1) - // get device window size - dExt.WindowSize, err = dExt.Driver.WindowSize() - if err != nil { - return nil, errors.Wrap(err, "get screen resolution failed") - } if driverOptions.withImageService { if dExt.ImageService, err = newVEDEMImageService(); err != nil { return nil, err diff --git a/hrp/pkg/uixt/ios_driver.go b/hrp/pkg/uixt/ios_driver.go index a569a7fb..fc15aaa4 100644 --- a/hrp/pkg/uixt/ios_driver.go +++ b/hrp/pkg/uixt/ios_driver.go @@ -192,21 +192,28 @@ func (wd *wdaDriver) BatteryInfo() (batteryInfo BatteryInfo, err error) { func (wd *wdaDriver) WindowSize() (size Size, err error) { // [[FBRoute GET:@"/window/size"] respondWithTarget:self action:@selector(handleGetWindowSize:)] - var rawResp rawResponse - if rawResp, err = wd.httpGET("/session", wd.sessionId, "/window/size"); err != nil { - return Size{}, errors.Wrap(err, "get window size failed with wda") + if wd.windowSize != nil { + size = *wd.windowSize + } else { + var rawResp rawResponse + if rawResp, err = wd.httpGET("/session", wd.sessionId, "/window/size"); err != nil { + return Size{}, errors.Wrap(err, "get window size failed with wda") + } + reply := new(struct{ Value struct{ Size } }) + if err = json.Unmarshal(rawResp, reply); err != nil { + return Size{}, err + } + size = reply.Value.Size + scale, err := wd.Scale() + if err != nil { + return Size{}, errors.Wrap(err, "get window size scale failed") + } + size.Height = size.Height * int(scale) + size.Width = size.Width * int(scale) + wd.windowSize = &size } - reply := new(struct{ Value struct{ Size } }) - if err = json.Unmarshal(rawResp, reply); err != nil { - return Size{}, err - } - size = reply.Value.Size - scale, err := wd.Scale() - if err != nil { - return Size{}, errors.Wrap(err, "get window size scale failed") - } - size.Height = size.Height * int(scale) - size.Width = size.Width * int(scale) + + // check orientation orientation, err := wd.Orientation() if err != nil { log.Warn().Err(err).Msgf("window size get orientation failed, use default orientation") diff --git a/hrp/pkg/uixt/screenshot.go b/hrp/pkg/uixt/screenshot.go index fb00c98f..9b5b7469 100644 --- a/hrp/pkg/uixt/screenshot.go +++ b/hrp/pkg/uixt/screenshot.go @@ -44,11 +44,15 @@ func (dExt *DriverExt) GetScreenResult(options ...ActionOption) (screenResult *S return } + windowSize, err := dExt.Driver.WindowSize() + if err != nil { + return + } screenResult = &ScreenResult{ bufSource: bufSource, imagePath: imagePath, Tags: nil, - Resolution: dExt.WindowSize, + Resolution: windowSize, } // cache screen result dExt.Driver.GetSession().addScreenResult(screenResult) diff --git a/hrp/pkg/uixt/swipe.go b/hrp/pkg/uixt/swipe.go index 2536709a..c6afeedd 100644 --- a/hrp/pkg/uixt/swipe.go +++ b/hrp/pkg/uixt/swipe.go @@ -21,9 +21,14 @@ func assertRelative(p float64) bool { return p >= 0 && p <= 1 } +// TODO: remove this function func (dExt *DriverExt) SwipeUpUtil(count int64, options ...ActionOption) error { - width := dExt.WindowSize.Width - height := dExt.WindowSize.Height + windowSize, err := dExt.Driver.WindowSize() + if err != nil { + return err + } + width := windowSize.Width + height := windowSize.Height fromX := float64(width) * directionSlice[count%3][0] fromY := float64(height) * directionSlice[count%3][1] @@ -35,33 +40,23 @@ func (dExt *DriverExt) SwipeUpUtil(count int64, options ...ActionOption) error { // SwipeRelative swipe from relative position [fromX, fromY] to relative position [toX, toY] func (dExt *DriverExt) SwipeRelative(fromX, fromY, toX, toY float64, options ...ActionOption) error { - width := dExt.WindowSize.Width - height := dExt.WindowSize.Height - orientation, err := dExt.Driver.Orientation() - if err != nil { - log.Warn().Err(err).Msgf("swipe from (%v, %v) to (%v, %v) get orientation failed, use default orientation", - fromX, fromY, toX, toY) - orientation = OrientationPortrait - } - if !assertRelative(fromX) || !assertRelative(fromY) || !assertRelative(toX) || !assertRelative(toY) { return fmt.Errorf("fromX(%f), fromY(%f), toX(%f), toY(%f) must be less than 1", fromX, fromY, toX, toY) } - // 左转和右转都是"LANDSCAPE" - if orientation == OrientationPortrait { - fromX = float64(width) * fromX - fromY = float64(height) * fromY - toX = float64(width) * toX - toY = float64(height) * toY - } else { - fromX = float64(height) * fromX - fromY = float64(width) * fromY - toX = float64(height) * toX - toY = float64(width) * toY - } + windowSize, err := dExt.Driver.WindowSize() + if err != nil { + return err + } + width := windowSize.Width + height := windowSize.Height + + fromX = float64(width) * fromX + fromY = float64(height) * fromY + toX = float64(width) * toX + toY = float64(height) * toY return dExt.Driver.SwipeFloat(fromX, fromY, toX, toY, options...) } diff --git a/hrp/pkg/uixt/tap.go b/hrp/pkg/uixt/tap.go index da9792ee..345ca8bd 100644 --- a/hrp/pkg/uixt/tap.go +++ b/hrp/pkg/uixt/tap.go @@ -2,8 +2,6 @@ package uixt import ( "fmt" - - "github.com/rs/zerolog/log" ) func (dExt *DriverExt) TapAbsXY(x, y float64, options ...ActionOption) error { @@ -17,19 +15,12 @@ func (dExt *DriverExt) TapXY(x, y float64, options ...ActionOption) error { return fmt.Errorf("x, y percentage should be <= 1, got x=%v, y=%v", x, y) } - orientation, err := dExt.Driver.Orientation() + windowSize, err := dExt.Driver.WindowSize() if err != nil { - log.Warn().Err(err).Msgf("tap (%v, %v) get orientation failed, use default orientation", - x, y) - orientation = OrientationPortrait - } - if orientation == OrientationPortrait { - x = x * float64(dExt.WindowSize.Width) - y = y * float64(dExt.WindowSize.Height) - } else { - x = x * float64(dExt.WindowSize.Height) - y = y * float64(dExt.WindowSize.Width) + return err } + x = x * float64(windowSize.Width) + y = y * float64(windowSize.Height) return dExt.TapAbsXY(x, y, options...) } @@ -84,19 +75,13 @@ func (dExt *DriverExt) DoubleTapXY(x, y float64) error { if x > 1 || y > 1 { return fmt.Errorf("x, y percentage should be < 1, got x=%v, y=%v", x, y) } - orientation, err := dExt.Driver.Orientation() + + windowSize, err := dExt.Driver.WindowSize() if err != nil { - log.Warn().Err(err).Msgf("tap (%v, %v) get orientation failed, use default orientation", - x, y) - orientation = OrientationPortrait - } - if orientation == OrientationPortrait { - x = x * float64(dExt.WindowSize.Width) - y = y * float64(dExt.WindowSize.Height) - } else { - x = x * float64(dExt.WindowSize.Height) - y = y * float64(dExt.WindowSize.Width) + return err } + x = x * float64(windowSize.Width) + y = y * float64(windowSize.Height) return dExt.Driver.DoubleTapFloat(x, y) }