-
-
Notifications
You must be signed in to change notification settings - Fork 426
/
AndroidViewGestureTargetLocator.java
85 lines (73 loc) · 2.84 KB
/
AndroidViewGestureTargetLocator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package io.sentry.android.core.internal.gestures;
import android.content.res.Resources;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ScrollView;
import androidx.core.view.ScrollingView;
import io.sentry.internal.gestures.GestureTargetLocator;
import io.sentry.internal.gestures.UiElement;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ApiStatus.Internal
public final class AndroidViewGestureTargetLocator implements GestureTargetLocator {
private final boolean isAndroidXAvailable;
private final int[] coordinates = new int[2];
public AndroidViewGestureTargetLocator(final boolean isAndroidXAvailable) {
this.isAndroidXAvailable = isAndroidXAvailable;
}
@Override
public @Nullable UiElement locate(
@NotNull Object root, float x, float y, UiElement.Type targetType) {
if (!(root instanceof View)) {
return null;
}
final View view = (View) root;
if (touchWithinBounds(view, x, y)) {
if (targetType == UiElement.Type.CLICKABLE && isViewTappable(view)) {
return createUiElement(view);
} else if (targetType == UiElement.Type.SCROLLABLE
&& isViewScrollable(view, isAndroidXAvailable)) {
return createUiElement(view);
}
}
return null;
}
private UiElement createUiElement(final @NotNull View targetView) {
try {
final String resourceName = ViewUtils.getResourceId(targetView);
@Nullable String className = targetView.getClass().getCanonicalName();
if (className == null) {
className = targetView.getClass().getSimpleName();
}
return new UiElement(targetView, className, resourceName, null);
} catch (Resources.NotFoundException ignored) {
return null;
}
}
private boolean touchWithinBounds(final @NotNull View view, final float x, final float y) {
view.getLocationOnScreen(coordinates);
int vx = coordinates[0];
int vy = coordinates[1];
int w = view.getWidth();
int h = view.getHeight();
return !(x < vx || x > vx + w || y < vy || y > vy + h);
}
private static boolean isViewTappable(final @NotNull View view) {
return view.isClickable() && view.getVisibility() == View.VISIBLE;
}
private static boolean isViewScrollable(
final @NotNull View view, final boolean isAndroidXAvailable) {
return (isJetpackScrollingView(view, isAndroidXAvailable)
|| AbsListView.class.isAssignableFrom(view.getClass())
|| ScrollView.class.isAssignableFrom(view.getClass()))
&& view.getVisibility() == View.VISIBLE;
}
private static boolean isJetpackScrollingView(
final @NotNull View view, final boolean isAndroidXAvailable) {
if (!isAndroidXAvailable) {
return false;
}
return ScrollingView.class.isAssignableFrom(view.getClass());
}
}