blob: 99fa7274c21f0e251db21b2aaf04532f4af88df5 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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 android.accessibilityservice.cts.utils;
import android.accessibility.cts.common.InstrumentedAccessibilityService;
import android.accessibilityservice.AccessibilityService.GestureResultCallback;
import android.accessibilityservice.GestureDescription;
import android.accessibilityservice.GestureDescription.StrokeDescription;
import android.graphics.Path;
import android.graphics.PointF;
import android.view.ViewConfiguration;
import java.util.concurrent.CompletableFuture;
public class GestureUtils {
private GestureUtils() {}
public static CompletableFuture<Void> dispatchGesture(
InstrumentedAccessibilityService service,
GestureDescription gesture) {
CompletableFuture<Void> result = new CompletableFuture<>();
GestureResultCallback callback = new GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
result.complete(null);
}
@Override
public void onCancelled(GestureDescription gestureDescription) {
result.cancel(false);
}
};
service.runOnServiceSync(() -> {
if (!service.dispatchGesture(gesture, callback, null)) {
result.completeExceptionally(new IllegalStateException());
}
});
return result;
}
public static StrokeDescription pointerDown(PointF point) {
return new StrokeDescription(path(point), 0, ViewConfiguration.getTapTimeout(), true);
}
public static StrokeDescription pointerUp(StrokeDescription lastStroke) {
return lastStroke.continueStroke(path(lastPointOf(lastStroke)),
endTimeOf(lastStroke), ViewConfiguration.getTapTimeout(), false);
}
public static PointF lastPointOf(StrokeDescription stroke) {
float[] p = stroke.getPath().approximate(0.3f);
return new PointF(p[p.length - 2], p[p.length - 1]);
}
public static StrokeDescription click(PointF point) {
return new StrokeDescription(path(point), 0, ViewConfiguration.getTapTimeout());
}
public static StrokeDescription longClick(PointF point) {
return new StrokeDescription(path(point), 0,
ViewConfiguration.getLongPressTimeout() * 3 / 2);
}
public static StrokeDescription swipe(PointF from, PointF to) {
return swipe(from, to, ViewConfiguration.getTapTimeout());
}
public static StrokeDescription swipe(PointF from, PointF to, long duration) {
return new StrokeDescription(path(from, to), 0, duration);
}
public static StrokeDescription drag(StrokeDescription from, PointF to) {
return from.continueStroke(
path(lastPointOf(from), to),
endTimeOf(from), ViewConfiguration.getTapTimeout(), true);
}
public static Path path(PointF first, PointF... rest) {
Path path = new Path();
path.moveTo(first.x, first.y);
for (PointF point : rest) {
path.lineTo(point.x, point.y);
}
return path;
}
public static StrokeDescription startingAt(long timeMs, StrokeDescription prototype) {
return new StrokeDescription(
prototype.getPath(), timeMs, prototype.getDuration(), prototype.willContinue());
}
public static long endTimeOf(StrokeDescription stroke) {
return stroke.getStartTime() + stroke.getDuration();
}
public static float distance(PointF a, PointF b) {
if (a == null) throw new NullPointerException();
if (b == null) throw new NullPointerException();
return (float) Math.hypot(a.x - b.x, a.y - b.y);
}
public static PointF add(PointF a, float x, float y) {
return new PointF(a.x + x, a.y + y);
}
public static PointF add(PointF a, PointF b) {
return add(a, b.x, b.y);
}
public static PointF diff(PointF a, PointF b) {
return add(a, -b.x, -b.y);
}
public static PointF negate(PointF p) {
return times(-1, p);
}
public static PointF times(float mult, PointF p) {
return new PointF(p.x * mult, p.y * mult);
}
public static float length(PointF p) {
return (float) Math.hypot(p.x, p.y);
}
public static PointF ceil(PointF p) {
return new PointF((float) Math.ceil(p.x), (float) Math.ceil(p.y));
}
}