/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.appium.android.bootstrap; import android.graphics.Rect; import com.android.uiautomator.core.UiDevice; import com.android.uiautomator.core.UiObjectNotFoundException; import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException; import io.appium.android.bootstrap.utils.Point; public abstract class PositionHelper { /** * Given a position, it will return either the position based on percentage * (by passing in a double between 0 and 1) or absolute position based on the * coordinates entered. * * @param pointCoord The position to translate. * @param length Length of side to use for percentage positions. * @param offset Position offset. * @return */ private static double translateCoordinate(double pointCoord, double length, double offset) { double translatedCoord = 0; if (pointCoord == 0) { translatedCoord = length * 0.5; } else if (Math.abs(pointCoord) > 0 && Math.abs(pointCoord) < 1) { translatedCoord = length * pointCoord; } else { translatedCoord = pointCoord; } return translatedCoord + offset; } /** * Translates coordinates relative to an element rectangle into absolute coordinates. * * @param point A point in relative coordinates. * @param displayRect The display rectangle to which the point is relative. * @param offsets X and Y values by which to offset the point. These are typically * the absolute coordinates of the display rectangle. * @param shouldCheckBounds Throw if the translated point is outside displayRect? * @return * @throws UiObjectNotFoundException * @throws InvalidCoordinatesException */ public static Point getAbsolutePosition(final Point point, final Rect displayRect, final Point offsets, final boolean shouldCheckBounds) throws UiObjectNotFoundException, InvalidCoordinatesException { final Point absolutePosition = new Point(); absolutePosition.x = translateCoordinate(point.x, displayRect.width(), offsets.x); absolutePosition.y = translateCoordinate(point.y, displayRect.height(), offsets.y); if (shouldCheckBounds && !displayRect.contains(absolutePosition.x.intValue(), absolutePosition.y.intValue())) { throw new InvalidCoordinatesException("Coordinate " + absolutePosition.toString() + " is outside of element rect: " + displayRect.toShortString()); } return absolutePosition; } public static Point getDeviceAbsPos(final Point point) throws UiObjectNotFoundException, InvalidCoordinatesException { final UiDevice d = UiDevice.getInstance(); final Rect displayRect = new Rect(0, 0, d.getDisplayWidth(), d.getDisplayHeight()); Logger.debug("Display bounds: " + displayRect.toShortString()); return getAbsolutePosition(point, displayRect, new Point(), true); } }