Home | History | Annotate | Download | only in scroll
      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 package com.google.android.droiddriver.scroll;
     17 
     18 import com.google.android.droiddriver.UiElement;
     19 import com.google.android.droiddriver.actions.ScrollDirection;
     20 import com.google.android.droiddriver.scroll.Direction.LogicalDirection;
     21 import com.google.android.droiddriver.scroll.Direction.PhysicalToLogicalConverter;
     22 import com.google.common.base.Predicate;
     23 import com.google.common.base.Predicates;
     24 
     25 import java.util.List;
     26 
     27 /**
     28  * Base {@link SentinelStrategy} for common code.
     29  */
     30 public abstract class AbstractSentinelStrategy implements SentinelStrategy {
     31 
     32   /**
     33    * Gets sentinel based on {@link Predicate}.
     34    */
     35   public static abstract class GetStrategy {
     36     protected final Predicate<? super UiElement> predicate;
     37     protected final String description;
     38 
     39     protected GetStrategy(Predicate<? super UiElement> predicate, String description) {
     40       this.predicate = predicate;
     41       this.description = description;
     42     }
     43 
     44     public UiElement getSentinel(UiElement parent) {
     45       return getSentinel(parent.getChildren(predicate));
     46     }
     47 
     48     protected abstract UiElement getSentinel(List<UiElement> children);
     49 
     50     @Override
     51     public String toString() {
     52       return description;
     53     }
     54   }
     55 
     56   /**
     57    * Decorates an existing {@link GetStrategy} by adding another
     58    * {@link Predicate}.
     59    */
     60   public static class MorePredicateGetStrategy extends GetStrategy {
     61     private final GetStrategy original;
     62 
     63     public MorePredicateGetStrategy(GetStrategy original,
     64         Predicate<? super UiElement> extraPredicate, String extraDescription) {
     65       super(Predicates.and(original.predicate, extraPredicate), extraDescription
     66           + original.description);
     67       this.original = original;
     68     }
     69 
     70     @Override
     71     protected UiElement getSentinel(List<UiElement> children) {
     72       return original.getSentinel(children);
     73     }
     74   }
     75 
     76   /**
     77    * Returns the first child as the sentinel.
     78    */
     79   public static final GetStrategy FIRST_CHILD_GETTER = new GetStrategy(Predicates.alwaysTrue(),
     80       "FIRST_CHILD") {
     81     @Override
     82     protected UiElement getSentinel(List<UiElement> children) {
     83       return children.get(0);
     84     }
     85   };
     86 
     87   /**
     88    * Returns the last child as the sentinel.
     89    */
     90   public static final GetStrategy LAST_CHILD_GETTER = new GetStrategy(Predicates.alwaysTrue(),
     91       "LAST_CHILD") {
     92     @Override
     93     protected UiElement getSentinel(List<UiElement> children) {
     94       return children.get(children.size() - 1);
     95     }
     96   };
     97 
     98   /**
     99    * Returns the second child as the sentinel. Useful when the activity shows a
    100    * fixed first child.
    101    */
    102   public static final GetStrategy SECOND_CHILD_GETTER = new GetStrategy(Predicates.alwaysTrue(),
    103       "SECOND_CHILD") {
    104     @Override
    105     protected UiElement getSentinel(List<UiElement> children) {
    106       return children.get(1);
    107     }
    108   };
    109 
    110   protected final GetStrategy backwardGetStrategy;
    111   protected final GetStrategy forwardGetStrategy;
    112   protected final PhysicalToLogicalConverter physicalToLogicalConverter;
    113 
    114   public AbstractSentinelStrategy(GetStrategy backwardGetStrategy, GetStrategy forwardGetStrategy,
    115       PhysicalToLogicalConverter physicalToLogicalConverter) {
    116     this.backwardGetStrategy = backwardGetStrategy;
    117     this.forwardGetStrategy = forwardGetStrategy;
    118     this.physicalToLogicalConverter = physicalToLogicalConverter;
    119   }
    120 
    121   protected UiElement getSentinel(UiElement parent, ScrollDirection direction) {
    122     LogicalDirection logicalDirection = physicalToLogicalConverter.toLogicalDirection(direction);
    123     if (logicalDirection == LogicalDirection.BACKWARD) {
    124       return backwardGetStrategy.getSentinel(parent);
    125     } else {
    126       return forwardGetStrategy.getSentinel(parent);
    127     }
    128   }
    129 
    130   @Override
    131   public String toString() {
    132     return String.format("{backwardGetStrategy=%s, forwardGetStrategy=%s}", backwardGetStrategy,
    133         forwardGetStrategy);
    134   }
    135 }
    136