18e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le/*
21194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jin * Copyright (C) 2013 DroidDriver committers
38e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le *
48e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * Licensed under the Apache License, Version 2.0 (the "License");
58e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * you may not use this file except in compliance with the License.
68e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * You may obtain a copy of the License at
78e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le *
88e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le *      http://www.apache.org/licenses/LICENSE-2.0
98e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le *
108e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * Unless required by applicable law or agreed to in writing, software
118e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * distributed under the License is distributed on an "AS IS" BASIS,
128e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * See the License for the specific language governing permissions and
148e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le * limitations under the License.
158e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le */
168e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
171194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jinpackage com.google.android.droiddriver.actions;
188e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
19f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jinimport android.graphics.Rect;
20f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jinimport android.os.SystemClock;
21f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jinimport android.view.ViewConfiguration;
22f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin
231194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jinimport com.google.android.droiddriver.UiElement;
241194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jinimport com.google.android.droiddriver.util.Events;
258e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
268e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le/**
27f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin * An action that does clicks on an UiElement.
288e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le */
29a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jinpublic abstract class ClickAction extends EventAction {
3021a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
3121a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public static final ClickAction SINGLE = new SingleClick(1000L);
3221a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public static final ClickAction LONG = new LongClick(1000L);
3321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public static final ClickAction DOUBLE = new DoubleClick(1000L);
3421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
3521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  private static final long CLICK_DURATION_MILLIS = 100L;
3621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
3721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public static class DoubleClick extends ClickAction {
3821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    public DoubleClick(long timeoutMillis) {
3921a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      super(timeoutMillis);
4021a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    }
4121a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
42f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    @Override
43f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    public boolean perform(InputInjector injector, UiElement element) {
44a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin      SINGLE.perform(element);
45a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin      SINGLE.perform(element);
46f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin      return true;
47f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    }
4821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  }
4921a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
500319e7c14a536a11851cc30cfa57241ce90fec11Kevin Jin  public static class LongClick extends ClickAction {
5121a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    public LongClick(long timeoutMillis) {
5221a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      super(timeoutMillis);
5321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    }
5421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
55f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    @Override
56f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    public boolean perform(InputInjector injector, UiElement element) {
577dde4b200c490587409e0301e58261210e7a5896Tony Wickham      Rect elementRect = element.getVisibleBounds();
58f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin      long downTime = Events.touchDown(injector, elementRect.centerX(), elementRect.centerY());
59f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin      // see android.test.TouchUtils - *1.5 to make sure it's long press
60f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin      SystemClock.sleep((long) (ViewConfiguration.getLongPressTimeout() * 1.5));
61f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin      Events.touchUp(injector, downTime, elementRect.centerX(), elementRect.centerY());
62f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin      return true;
63f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    }
6421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  }
6521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
6621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public static class SingleClick extends ClickAction {
6721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    public SingleClick(long timeoutMillis) {
6821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      super(timeoutMillis);
6921a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    }
7021a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
71f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    @Override
72f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    public boolean perform(InputInjector injector, UiElement element) {
7321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      Rect elementRect = element.getVisibleBounds();
7421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      long downTime = Events.touchDown(injector, elementRect.centerX(), elementRect.centerY());
7521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      // UiAutomator clickAndSync does this, while
7621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      // android.test.TouchUtils#clickView sleep 1000
7721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      SystemClock.sleep(CLICK_DURATION_MILLIS);
7821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin      Events.touchUp(injector, downTime, elementRect.centerX(), elementRect.centerY());
79f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin      return true;
80f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin    }
8121a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  }
8221a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin
8321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  protected ClickAction(long timeoutMillis) {
8421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    super(timeoutMillis);
8521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  }
868e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
8721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  @Override
8821a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  public String toString() {
8921a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin    return getClass().getSimpleName();
9021a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin  }
918e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le}
92