Updated and fixed support for flick using touch actions.

This commit is contained in:
xuru
2013-04-08 17:34:11 -05:00
parent 1869e20ac9
commit dba5259218
5 changed files with 84 additions and 36 deletions
+1 -1
View File
@@ -554,7 +554,7 @@ Android.prototype.fakeFlick = function(xSpeed, ySpeed, swipe, cb) {
};
Android.prototype.fakeFlickElement = function(elementId, xoffset, yoffset, speed, cb) {
cb(new NotYetImplementedError(), null);
this.proxy(["element:flick", {xoffset: xoffset, yoffset: yoffset, speed: speed, elementId: elementId}], cb);
};
Android.prototype.swipe = function(startX, startY, endX, endY, duration, touchCount, elId, cb) {
@@ -54,6 +54,7 @@ public class AndroidElement {
InvalidCoordinatesException {
final Rect rect = el.getBounds();
final Point pos = new Point();
Logger.debug("Element bounds: " + rect.toShortString());
if (point.x == 0) {
pos.x = rect.width() * 0.5 + rect.left;
@@ -41,7 +41,7 @@ public abstract class CommandHandler {
return retPos;
}
protected static Point GetAbsPos(final Point point)
protected static Point GetDeviceAbsPos(final Point point)
throws InvalidCoordinatesException {
final UiDevice d = UiDevice.getInstance();
final Point retPos = new Point(point); // copy inputed point
@@ -2,13 +2,19 @@ package io.appium.android.bootstrap.handler;
import io.appium.android.bootstrap.AndroidCommand;
import io.appium.android.bootstrap.AndroidCommandResult;
import io.appium.android.bootstrap.AndroidElement;
import io.appium.android.bootstrap.CommandHandler;
import io.appium.android.bootstrap.Logger;
import io.appium.android.bootstrap.exceptions.ElementNotInHashException;
import io.appium.android.bootstrap.exceptions.InvalidCoordinatesException;
import io.appium.android.bootstrap.utils.Point;
import java.util.Hashtable;
import org.json.JSONException;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObjectNotFoundException;
/**
* This handler is used to flick elements in the Android UI.
@@ -20,6 +26,32 @@ import com.android.uiautomator.core.UiDevice;
*/
public class Flick extends CommandHandler {
private Point calculateEndPoint(final Point start, final Integer xSpeed,
final Integer ySpeed) {
final UiDevice d = UiDevice.getInstance();
final Point end = new Point();
final double speedRatio = (double) xSpeed / ySpeed;
double xOff;
double yOff;
final double value = Math.min(d.getDisplayHeight(), d.getDisplayWidth());
if (speedRatio < 1) {
yOff = value / 4;
xOff = value / 4 * speedRatio;
} else {
xOff = value / 4;
yOff = value / 4 / speedRatio;
}
xOff = Integer.signum(xSpeed) * xOff;
yOff = Integer.signum(ySpeed) * yOff;
end.x = start.x + xOff;
end.y = start.y + yOff;
return end;
}
/*
* @param command The {@link AndroidCommand} used for this handler.
*
@@ -33,44 +65,59 @@ public class Flick extends CommandHandler {
@Override
public AndroidCommandResult execute(final AndroidCommand command)
throws JSONException {
if (!command.isElementCommand()) {
final Hashtable<String, Object> params = command.params();
final Integer xSpeed = (Integer) params.get("xSpeed");
final Integer ySpeed = (Integer) params.get("ySpeed");
Point start = new Point(0.5, 0.5);
Point end = new Point();
Double steps = null;
final UiDevice d = UiDevice.getInstance();
final Hashtable<String, Object> params = command.params();
final UiDevice d = UiDevice.getInstance();
final Integer screenX = d.getDisplayWidth();
final Integer screenY = d.getDisplayHeight();
final Integer startX = screenX / 2;
final Integer startY = screenY / 2;
final Double speedRatio = (double) xSpeed / ySpeed;
Integer xOff;
Integer yOff;
if (command.isElementCommand()) {
AndroidElement el;
try {
el = command.getElement();
start = el.getAbsolutePosition(start);
final Integer xoffset = (Integer) params.get("xoffset");
final Integer yoffset = (Integer) params.get("yoffset");
final Integer speed = (Integer) params.get("speed");
if (speedRatio < 1) {
yOff = screenY / 4;
xOff = (int) ((double) screenX / 4 * speedRatio);
} else {
xOff = screenX / 4;
yOff = (int) ((double) screenY / 4 / speedRatio);
}
steps = 1250.0 / speed + 1;
end.x = start.x + xoffset;
end.y = start.y + yoffset;
final Integer endX = startX + Integer.signum(xSpeed) * xOff;
final Integer endY = startY + Integer.signum(ySpeed) * yOff;
final Double speed = Math.max(1250,
Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
final Integer steps = 1250 / speed.intValue() + 1;
final boolean res = d.swipe(startX, startY, endX, endY, steps);
if (res) {
return getSuccessResult(res);
} else {
return getErrorResult("Flick did not complete successfully");
} catch (final ElementNotInHashException e) {
return getErrorResult(e.getMessage());
} catch (final UiObjectNotFoundException e) {
return getErrorResult(e.getMessage());
} catch (final InvalidCoordinatesException e) {
return getErrorResult(e.getMessage());
}
} else {
return getErrorResult("Flick not yet implemented on the element level.");
try {
final Integer xSpeed = (Integer) params.get("xSpeed");
final Integer ySpeed = (Integer) params.get("ySpeed");
final Double speed = Math.min(1250.0,
Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed));
steps = 1250.0 / speed + 1;
start = GetDeviceAbsPos(start);
end = calculateEndPoint(start, xSpeed, ySpeed);
} catch (final InvalidCoordinatesException e) {
return getErrorResult(e.getMessage());
}
}
steps = Math.abs(steps);
Logger.info("Flicking from " + start.toString() + " to " + end.toString()
+ " with steps: " + steps.intValue());
final boolean res = d.swipe(start.x.intValue(), start.y.intValue(),
end.x.intValue(), end.y.intValue(), steps.intValue());
if (res) {
return getSuccessResult(res);
} else {
return getErrorResult("Flick did not complete successfully");
}
}
}
@@ -60,8 +60,8 @@ public class Swipe extends CommandHandler {
}
} else {
try {
absStartPos = GetAbsPos(start);
absEndPos = GetAbsPos(end);
absStartPos = GetDeviceAbsPos(start);
absEndPos = GetDeviceAbsPos(end);
} catch (final InvalidCoordinatesException e) {
return getErrorResult(e.getMessage());
}