Home | History | Annotate | Download | only in base
      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 
     17 package io.appium.droiddriver.base;
     18 
     19 import android.os.SystemClock;
     20 
     21 import java.util.Collection;
     22 import java.util.LinkedList;
     23 
     24 import io.appium.droiddriver.DroidDriver;
     25 import io.appium.droiddriver.Poller;
     26 import io.appium.droiddriver.exceptions.NoRunningActivityException;
     27 import io.appium.droiddriver.exceptions.TimeoutException;
     28 import io.appium.droiddriver.finders.Finder;
     29 
     30 /**
     31  * Default implementation of a {@link Poller}.
     32  */
     33 public class DefaultPoller implements Poller {
     34   private final Collection<TimeoutListener> timeoutListeners = new LinkedList<TimeoutListener>();
     35   private final Collection<PollingListener> pollingListeners = new LinkedList<PollingListener>();
     36   private long timeoutMillis = 10000;
     37   private long intervalMillis = 500;
     38 
     39   @Override
     40   public long getIntervalMillis() {
     41     return intervalMillis;
     42   }
     43 
     44   @Override
     45   public void setIntervalMillis(long intervalMillis) {
     46     this.intervalMillis = intervalMillis;
     47   }
     48 
     49   @Override
     50   public long getTimeoutMillis() {
     51     return timeoutMillis;
     52   }
     53 
     54   @Override
     55   public void setTimeoutMillis(long timeoutMillis) {
     56     this.timeoutMillis = timeoutMillis;
     57   }
     58 
     59   @Override
     60   public <T> T pollFor(DroidDriver driver, Finder finder, ConditionChecker<T> checker) {
     61     return pollFor(driver, finder, checker, timeoutMillis);
     62   }
     63 
     64   @Override
     65   public <T> T pollFor(DroidDriver driver, Finder finder, ConditionChecker<T> checker,
     66       long timeoutMillis) {
     67     long end = SystemClock.uptimeMillis() + timeoutMillis;
     68     while (true) {
     69       try {
     70         try {
     71           driver.refreshUiElementTree();
     72         } catch (NoRunningActivityException nrae) {
     73           if (checker == GONE) {
     74             return null;
     75           }
     76           throw nrae;
     77         }
     78         return checker.check(driver, finder);
     79       } catch (UnsatisfiedConditionException uce) {
     80         // fall through to poll
     81       }
     82 
     83       for (PollingListener pollingListener : pollingListeners) {
     84         pollingListener.onPolling(driver, finder);
     85       }
     86 
     87       long remainingMillis = end - SystemClock.uptimeMillis();
     88       if (remainingMillis < 0) {
     89         for (TimeoutListener timeoutListener : timeoutListeners) {
     90           timeoutListener.onTimeout(driver, finder);
     91         }
     92         throw new TimeoutException(String.format(
     93             "Timed out after %d milliseconds waiting for %s %s", timeoutMillis, finder, checker));
     94       }
     95       SystemClock.sleep(Math.min(intervalMillis, remainingMillis));
     96     }
     97   }
     98 
     99   @Override
    100   public ListenerRemover addListener(final TimeoutListener timeoutListener) {
    101     timeoutListeners.add(timeoutListener);
    102     return new ListenerRemover() {
    103       @Override
    104       public void remove() {
    105         timeoutListeners.remove(timeoutListener);
    106       }
    107     };
    108   }
    109 
    110   @Override
    111   public ListenerRemover addListener(final PollingListener pollingListener) {
    112     pollingListeners.add(pollingListener);
    113     return new ListenerRemover() {
    114       @Override
    115       public void remove() {
    116         pollingListeners.remove(pollingListener);
    117       }
    118     };
    119   }
    120 }
    121