camera: Add ptzControl type encapsulate ptz actions
BUG=b:187889721
TEST=tast run <DUT> camera.CCAUIPTZ
Change-Id: I59199385a590a36145745399daea7587492650d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/tast-tests/+/2947267
Tested-by: Inker Kuo <inker@chromium.org>
Auto-Submit: Inker Kuo <inker@chromium.org>
Reviewed-by: Wei Lee <wtlee@chromium.org>
Reviewed-by: Gabor Zsolt Magda <gabormagda@google.com>
Commit-Queue: Inker Kuo <inker@chromium.org>
(cherry picked from commit 42161a38b29c8734436de3457db6b5309af33ab1)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/tast-tests/+/2982654
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
diff --git a/src/chromiumos/tast/local/bundles/cros/camera/cca_ui_ptz.go b/src/chromiumos/tast/local/bundles/cros/camera/cca_ui_ptz.go
index 6055840..ff7837f 100644
--- a/src/chromiumos/tast/local/bundles/cros/camera/cca_ui_ptz.go
+++ b/src/chromiumos/tast/local/bundles/cros/camera/cca_ui_ptz.go
@@ -133,6 +133,103 @@
return &image.Rectangle{*minPt, *maxPt}, nil
}
+// calShift checks the size and calculates the x-y shift between |r| and |r2|.
+func calShift(r, r2 *image.Rectangle) (*image.Point, error) {
+ abs := func(n int) int {
+ if n < 0 {
+ return -n
+ }
+ return n
+ }
+
+ // The pattern should only shift without resizing.
+ sz := r.Size()
+ sz2 := r2.Size()
+
+ // Do all comparisons with 1px precision tolerance introduced by fake
+ // file VCD bilinear resizing implementation.
+ const precision = 1
+ if abs(sz.X-sz2.X) > precision {
+ return nil, errors.Errorf("inconsistent width, got %v; want %v", sz2.X, sz.X)
+ }
+ if abs(sz.Y-sz2.Y) > precision {
+ return nil, errors.Errorf("inconsistent height, got %v; want %v", sz2.Y, sz.Y)
+ }
+ return &image.Point{r2.Min.X - r.Min.X, r2.Min.Y - r.Min.Y}, nil
+}
+
+type ptzControl struct {
+ // ui is the UI toggled for moving preview in one of PTZ direction.
+ ui *cca.UIComponent
+ // testFunc tests pattern before and after ptz control applied moving in the target direction.
+ testFunc func(r, r2 *image.Rectangle) (bool, error)
+}
+
+var (
+ panLeft = ptzControl{&cca.PanLeftButton, func(r, r2 *image.Rectangle) (bool, error) {
+ shift, err := calShift(r, r2)
+ if err != nil {
+ return false, err
+ }
+ return shift.X < 0 && shift.Y == 0, nil
+ }}
+ panRight = ptzControl{&cca.PanRightButton, func(r, r2 *image.Rectangle) (bool, error) {
+ shift, err := calShift(r, r2)
+ if err != nil {
+ return false, err
+ }
+ return shift.X > 0 && shift.Y == 0, nil
+ }}
+ tiltDown = ptzControl{&cca.TiltDownButton, func(r, r2 *image.Rectangle) (bool, error) {
+ shift, err := calShift(r, r2)
+ if err != nil {
+ return false, err
+ }
+ return shift.X == 0 && shift.Y < 0, nil
+ }}
+ tiltUp = ptzControl{&cca.TiltUpButton, func(r, r2 *image.Rectangle) (bool, error) {
+ shift, err := calShift(r, r2)
+ if err != nil {
+ return false, err
+ }
+ return shift.X == 0 && shift.Y > 0, nil
+ }}
+ zoomIn = ptzControl{&cca.ZoomInButton, func(r, r2 *image.Rectangle) (bool, error) {
+ return r.Size().X < r2.Size().X && r.Size().Y < r2.Size().Y, nil
+ }}
+ zoomOut = ptzControl{&cca.ZoomOutButton, func(r, r2 *image.Rectangle) (bool, error) {
+ return r.Size().X > r2.Size().X && r.Size().Y > r2.Size().Y, nil
+ }}
+)
+
+// testToggle tests toggling the control |ctrl|.
+func (ctrl *ptzControl) testToggle(ctx context.Context, app *cca.App) error {
+ pRect, err := findPattern(ctx, app)
+ if err != nil {
+ return errors.Wrapf(err, "failed to find pattern before clicking %v: %v", ctrl.ui.Name, err)
+ }
+ if err := app.ClickPTZButton(ctx, *ctrl.ui); err != nil {
+ return errors.Wrapf(err, "failed to click: %v", err)
+ }
+ if err := testing.Poll(ctx, func(ctx context.Context) error {
+ rect, err := findPattern(ctx, app)
+ if err != nil {
+ return errors.Wrapf(err, "failed to find pattern after clicking %v: %v", ctrl.ui.Name, err)
+ }
+ result, err := ctrl.testFunc(pRect, rect)
+ if err != nil {
+ return testing.PollBreak(err)
+ }
+ if result {
+ return nil
+ }
+ return errors.Errorf("failed on testing UI with region before %v ; after %v", pRect, rect)
+ }, &testing.PollOptions{Interval: time.Second}); err != nil {
+ return errors.Wrapf(err, "failed to run %v test func: %v", ctrl.ui.Name, err)
+ }
+ return nil
+}
+
func CCAUIPTZ(ctx context.Context, s *testing.State) {
y4m, err := preparePattern()
if err != nil {
@@ -171,89 +268,22 @@
s.Fatal("Failed to open ptz panel: ", err)
}
- // Do all comparisons with 1px precision tolerance introduced by fake
- // file VCD bilinear resizing implementation.
- const precision = 1
- abs := func(n int) int {
- if n < 0 {
- return -n
- }
- return n
- }
- calShift := func(r, r2 *image.Rectangle) (*image.Point, error) {
- // The pattern should only shift without resizing.
- sz := r.Size()
- sz2 := r2.Size()
- if abs(sz.X-sz2.X) > precision {
- return nil, errors.Errorf("inconsistent width, got %v; want %v", sz2.X, sz.X)
- }
- if abs(sz.Y-sz2.Y) > precision {
- return nil, errors.Errorf("inconsistent height, got %v; want %v", sz2.Y, sz.Y)
- }
- return &image.Point{r2.Min.X - r.Min.X, r2.Min.Y - r.Min.Y}, nil
- }
-
- for _, tc := range []struct {
- ui cca.UIComponent
- testFunc func(r, r2 *image.Rectangle) (bool, error)
- }{
- {cca.ZoomInButton, func(r, r2 *image.Rectangle) (bool, error) {
- return r.Size().X < r2.Size().X && r.Size().Y < r2.Size().Y, nil
- }},
- {cca.PanLeftButton, func(r, r2 *image.Rectangle) (bool, error) {
- shift, err := calShift(r, r2)
- if err != nil {
- return false, err
- }
- return shift.X < 0 && shift.Y == 0, nil
- }},
- {cca.PanRightButton, func(r, r2 *image.Rectangle) (bool, error) {
- shift, err := calShift(r, r2)
- if err != nil {
- return false, err
- }
- return shift.X > 0 && shift.Y == 0, nil
- }},
- {cca.TiltDownButton, func(r, r2 *image.Rectangle) (bool, error) {
- shift, err := calShift(r, r2)
- if err != nil {
- return false, err
- }
- return shift.X == 0 && shift.Y < 0, nil
- }},
- {cca.TiltUpButton, func(r, r2 *image.Rectangle) (bool, error) {
- shift, err := calShift(r, r2)
- if err != nil {
- return false, err
- }
- return shift.X == 0 && shift.Y > 0, nil
- }},
- {cca.ZoomOutButton, func(r, r2 *image.Rectangle) (bool, error) {
- return r.Size().X > r2.Size().X && r.Size().Y > r2.Size().Y, nil
- }},
+ // Test move all controls. The controls need to be tested in order such
+ // that |zoomIn| before all other controls(For all other controls will
+ // be disabled in minimal zoom level as behavior of digital zoom
+ // camera), |panLeft| before |panRight| (For the initial pan level is 0
+ // with range [0, 15]) with initial mirror state, |tiltDown| before
+ // |tiltUp| (For the initial tilt level is 0 with range[0, 8]).
+ for _, control := range []ptzControl{
+ zoomIn,
+ panLeft,
+ panRight,
+ tiltDown,
+ tiltUp,
+ zoomOut,
} {
- pRect, err := findPattern(ctx, app)
- if err != nil {
- s.Fatalf("Failed to find pattern before clicking %v: %v", tc.ui.Name, err)
- }
- if err := app.ClickPTZButton(ctx, tc.ui); err != nil {
- s.Fatal("Failed to click: ", err)
- }
- if err := testing.Poll(ctx, func(ctx context.Context) error {
- rect, err := findPattern(ctx, app)
- if err != nil {
- s.Fatalf("Failed to find pattern after clicking %v: %v", tc.ui.Name, err)
- }
- result, err := tc.testFunc(pRect, rect)
- if err != nil {
- return testing.PollBreak(err)
- }
- if result {
- return nil
- }
- return errors.Errorf("failed on testing UI with region before %v ; after %v", pRect, rect)
- }, &testing.PollOptions{Interval: time.Second}); err != nil {
- s.Fatalf("Failed to run %v test func: %v", tc.ui.Name, err)
+ if err := control.testToggle(ctx, app); err != nil {
+ s.Fatal("Failed: ", err)
}
}
}