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