1/*
2 * Copyright (C) 2013 DroidDriver committers
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package io.appium.droiddriver;
18
19import io.appium.droiddriver.exceptions.ElementNotFoundException;
20import io.appium.droiddriver.finders.Finder;
21
22/**
23 * Interface for polling mechanism.
24 */
25public interface Poller {
26  /**
27   * Interface for a callback to be invoked when {@link #pollFor} times out.
28   */
29  interface TimeoutListener {
30    /**
31     * Called when {@link #pollFor} times out. Should return quickly (no
32     * polling).
33     */
34    void onTimeout(DroidDriver driver, Finder finder);
35  }
36
37  /**
38   * Interface for a callback to be invoked when {@link #pollFor} polls.
39   */
40  interface PollingListener {
41    /**
42     * Called when {@link #pollFor} polls. Should return quickly (no polling).
43     */
44    void onPolling(DroidDriver driver, Finder finder);
45  }
46  /**
47   * Interface for removing a listener.
48   */
49  interface ListenerRemover {
50    /**
51     * A ListenerRemover that does nothing. Can be used as initial value for
52     * ListenerRemovers.
53     */
54    ListenerRemover NOP_LISTENER_REMOVER = new ListenerRemover() {
55      @Override
56      public void remove() {}
57    };
58
59    /**
60     * Removes the associated listener.
61     */
62    void remove();
63  }
64
65  /**
66   * Used by Poller to check conditions.
67   *
68   * @param <T> type of the value returned by {@link #check}
69   */
70  interface ConditionChecker<T> {
71    /**
72     * Checks condition that overriding methods provide.
73     *
74     * @throws UnsatisfiedConditionException If the condition is not met
75     */
76    T check(DroidDriver driver, Finder finder) throws UnsatisfiedConditionException;
77  }
78
79  /** Thrown to indicate condition not met. Used in {@link ConditionChecker}. */
80  @SuppressWarnings("serial")
81  class UnsatisfiedConditionException extends Exception {
82  }
83
84  /**
85   * A ConditionChecker that returns the matching {@link UiElement}.
86   */
87  ConditionChecker<UiElement> EXISTS = new ConditionChecker<UiElement>() {
88    @Override
89    public UiElement check(DroidDriver driver, Finder finder) throws UnsatisfiedConditionException {
90      try {
91        return driver.find(finder);
92      } catch (ElementNotFoundException e) {
93        throw new UnsatisfiedConditionException();
94      }
95    }
96
97    @Override
98    public String toString() {
99      return "to appear";
100    }
101  };
102  /**
103   * A ConditionChecker that does not throw only if the matching
104   * {@link UiElement} is gone.
105   */
106  ConditionChecker<Void> GONE = new ConditionChecker<Void>() {
107    @Override
108    public Void check(DroidDriver driver, Finder finder) throws UnsatisfiedConditionException {
109      try {
110        // "find" does not call refreshUiElementTree, while "has" calls
111        driver.find(finder);
112        throw new UnsatisfiedConditionException();
113      } catch (ElementNotFoundException enfe) {
114        return null;
115      }
116    }
117
118    @Override
119    public String toString() {
120      return "to disappear";
121    }
122  };
123
124  /**
125   * Polls until {@code checker} does not throw
126   * {@link UnsatisfiedConditionException}, up to the default timeout.
127   *
128   * @return An object of type T returned by {@code checker}
129   */
130  <T> T pollFor(DroidDriver driver, Finder finder, ConditionChecker<T> checker);
131
132  /**
133   * Polls until {@code checker} does not throw
134   * {@link UnsatisfiedConditionException}, up to {@code timeoutMillis}.
135   *
136   * @return An object of type T returned by {@code checker}
137   */
138  <T> T pollFor(DroidDriver driver, Finder finder, ConditionChecker<T> checker, long timeoutMillis);
139
140  /**
141   * Adds a {@link TimeoutListener}.
142   */
143  ListenerRemover addListener(TimeoutListener timeoutListener);
144
145  /**
146   * Adds a {@link PollingListener}.
147   */
148  ListenerRemover addListener(PollingListener pollingListener);
149
150  /**
151   * Sets default timeoutMillis.
152   */
153  void setTimeoutMillis(long timeoutMillis);
154
155  /**
156   * @return default timeoutMillis
157   */
158  long getTimeoutMillis();
159
160  /**
161   * Sets intervalMillis.
162   */
163  void setIntervalMillis(long intervalMillis);
164
165  /**
166   * @return intervalMillis
167   */
168  long getIntervalMillis();
169}
170