/* * 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.handler; import android.graphics.Rect; import com.android.uiautomator.core.UiObjectNotFoundException; import io.appium.android.bootstrap.*; import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException; import io.appium.android.bootstrap.utils.Point; import org.json.JSONException; import java.util.ArrayList; import java.util.Hashtable; /** * This handler is and abstract class that contains all the common code for * touch event handlers. * */ public abstract class TouchEvent extends CommandHandler { protected AndroidElement el; protected int clickX; protected int clickY; protected Hashtable<String, Object> params; protected boolean isElement; /** * * @param command * The {@link AndroidCommand} * @return {@link AndroidCommandResult} * @throws JSONException * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { initalize(); try { params = command.params(); // isElementCommand doesn't check to see if we actually have an element // so getElement is used instead. try { if (command.getElement() != null) { isElement = true; } } catch (final Exception e) { isElement = false; } if (isElement) { // extract x and y from the element. el = command.getElement(); // check if element exists without wait if (!el.exists()) { throw new UiObjectNotFoundException("TouchEvent element does not exist."); } final Rect bounds = el.getVisibleBounds(); clickX = bounds.centerX(); clickY = bounds.centerY(); } else { // no element so extract x and y from params final Object paramX = params.get("x"); final Object paramY = params.get("y"); // these will be defaulted to 0.5 when passed to getDeviceAbsPos double targetX = 0; double targetY = 0; if (paramX != null) { targetX = Double.parseDouble(paramX.toString()); } if (paramY != null) { targetY = Double.parseDouble(paramY.toString()); } Point coords = new Point(targetX, targetY); coords = PositionHelper.getDeviceAbsPos(coords); clickX = coords.x.intValue(); clickY = coords.y.intValue(); } if (executeTouchEvent()) { return getSuccessResult(true); } } catch (final UiObjectNotFoundException e) { return new AndroidCommandResult(WDStatus.NO_SUCH_ELEMENT, e.getMessage()); } catch (final InvalidCoordinatesException e) { return new AndroidCommandResult(WDStatus.INVALID_ELEMENT_COORDINATES, e.getMessage()); } catch (final Exception e) { return getErrorResult(e.getMessage()); } return getErrorResult("Failed to execute touch event"); } protected abstract boolean executeTouchEvent() throws UiObjectNotFoundException; /** * Variables persist across executions. initialize must be called at the start * of execute. **/ private void initalize() { el = null; clickX = -1; clickY = -1; params = null; isElement = false; } protected void printEventDebugLine(final String methodName, final Integer... duration) { String extra = ""; if (duration.length > 0) { extra = ", duration: " + duration[0]; } Logger.debug("Performing " + methodName + " using element? " + isElement + " x: " + clickX + ", y: " + clickY + extra); } }