Merge "Passing MotionEvents all the way through." into androidx-master-dev
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/AndroidManifest.xml b/ui/ui-android-view/integration-tests/android-view-demos/src/main/AndroidManifest.xml
index ae42839..ea84e16e 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/AndroidManifest.xml
@@ -42,6 +42,5 @@
android:name=".ComposeScrollInAndroidScrollDifferentOrientation"
android:configChanges="orientation|screenSize"
android:label="ComposeScrollInAndroidScrollDifferentOrientation Activity" />
-
</application>
</manifest>
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/AndroidViewDemos.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/AndroidViewDemos.kt
index 8d539c6..86c9bf6 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/AndroidViewDemos.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/AndroidViewDemos.kt
@@ -22,5 +22,6 @@
val AndroidViewDemos = DemoCategory("AndroidView", listOf(
ComposeInAndroidDemos,
AndroidInComposeDemos,
+ ComplexTouchInterop,
ActivityDemo("WebComponent", WebComponentActivity::class)
))
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/ComplexInteractions.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/ComplexInteractions.kt
index efccc1a..9225eb10 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/ComplexInteractions.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/ComplexInteractions.kt
@@ -16,51 +16,102 @@
package androidx.ui.androidview.demos
-import android.content.Context
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.FrameLayout
+import android.widget.RelativeLayout
import androidx.compose.Composable
import androidx.compose.Recomposer
+import androidx.compose.foundation.Box
+import androidx.compose.state
+import androidx.ui.core.Alignment
import androidx.ui.core.ContextAmbient
+import androidx.ui.core.Modifier
import androidx.ui.core.setContent
import androidx.ui.demos.common.ComposableDemo
import androidx.ui.demos.common.DemoCategory
import androidx.compose.foundation.Text
+import androidx.compose.foundation.background
+import androidx.ui.graphics.Color
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
import androidx.ui.material.Button
+import androidx.ui.unit.dp
import androidx.ui.viewinterop.AndroidView
// TODO(b/158099918): Add this demo to AndroidViewDemos.kt once b/158099918 has been resolved.
@Suppress("unused")
val ComplexTouchInterop = DemoCategory("Complex Touch Interop", listOf(
- ComposableDemo("ReproOffsetIssue") { ComposeInAndroidInComposeEtcTargetingDemo() }
+ ComposableDemo("Compose in Android in Compose in Android") {
+ ComposeInAndroidInComposeEtcTargetingDemo() }
))
@Composable
fun ComposeInAndroidInComposeEtcTargetingDemo() {
val context = ContextAmbient.current
Column {
- Text("In this demo, there is a compose button inside Android, which is inside Compose, " +
- "which inside Android... and on so on for a few times. The conversions of " +
- "pointer input events at every level still work.")
- AndroidWithCompose(context) {
- AndroidWithCompose(context) {
- AndroidWithCompose(context) {
- Button( }) {
- Text("Click me")
- }
+ Text(
+ "In this demo, from the inside out, we have a Compose Button, wrapped in 2 Android " +
+ "FrameLayouts, wrapped in a Compose Box, wrapped in a Column (which also has " +
+ "this Text) which is then in the root AndroidComposeView."
+ )
+ Text(
+ "Each node in our tree affects the position of the button and the pointer input " +
+ "events translate from Android to compose a couple of times and everything " +
+ "still works."
+ )
+ Box(
+ Modifier
+ .fillMaxSize()
+ .background(color = Color(0xFF777777))
+ .padding(48.dp)
+ ) {
+
+ AndroidView(
+ modifier = Modifier.weight(1f),
+ view =
+ FrameLayout(context).apply {
+ setPadding(100, 100, 100, 100)
+ setBackgroundColor(0xFF888888.toInt())
+ layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
+ addView(
+ FrameLayout(context).apply {
+ setPadding(100, 100, 100, 100)
+ setBackgroundColor(0xFF999999.toInt())
+ layoutParams =
+ RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT).apply {
+ addRule(RelativeLayout.CENTER_IN_PARENT)
+ }
+ setContent(Recomposer.current()) {
+ Box(
+ Modifier
+ .background(color = Color(0xFFAAAAAA))
+ .fillMaxSize()
+ .wrapContentSize(Alignment.Center)
+ ) {
+ colorButton()
+ }
+ }
+ }
+ )
}
- }
+ )
}
}
}
@Composable
-fun AndroidWithCompose(context: Context, children: @Composable () -> Unit) {
- val anotherLayout = FrameLayout(context).also { view ->
- view.setContent(Recomposer.current()) {
- children()
+fun colorButton() {
+ val state = state { false }
+ val color =
+ if (state.value) {
+ Color.Red
+ } else {
+ Color.Blue
}
- view.setPadding(50, 50, 50, 50)
+ Button( state.value = !state.value }, backgroundColor = color) {
+ Text("Click me")
}
- AndroidView(anotherLayout)
}
\ No newline at end of file
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
index c01c8b5..055e179 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/PointerInputInteropAndroidInCompose.kt
@@ -33,6 +33,7 @@
import androidx.ui.geometry.Offset
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.preferredHeight
@@ -50,6 +51,9 @@
},
ComposableDemo("Android scroll in Compose scroll (same orientation)") {
AndroidScrollInComposeScrollSameOrientation()
+ },
+ ComposableDemo("2 ScrollViews as separate children of Compose") {
+ TwoAndroidScrollViewsInCompose()
}
))
@@ -108,10 +112,10 @@
)
Box(
Modifier
- .tapGestureFilter(onTap)
.fillMaxSize()
.wrapContentSize(Alignment.Center)
.preferredSize(240.dp)
+ .tapGestureFilter(onTap)
) {
AndroidView(R.layout.android_tap_in_compose_tap) { view ->
theView = view
@@ -212,4 +216,19 @@
}
}
}
+}
+
+@Composable
+private fun TwoAndroidScrollViewsInCompose() {
+ Column {
+ Text(
+ "Below are two Android Scrollviews that are nested in two different children of " +
+ "Compose. The user should be able to scroll each independently at the same " +
+ "time, but given that we currently don't split motion, this is not work."
+ )
+ Row {
+ AndroidView(R.layout.android_scrollview, Modifier.weight(2f))
+ AndroidView(R.layout.android_scrollview, Modifier.weight(1f))
+ }
+ }
}
\ No newline at end of file
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/res/layout/android_scrollview.xml b/ui/ui-android-view/integration-tests/android-view-demos/src/main/res/layout/android_scrollview.xml
new file mode 100644
index 0000000..73022bc
--- /dev/null
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/res/layout/android_scrollview.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2020 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.
+ -->
+
+<ScrollView android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="1" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="2" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="3" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="4" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="5" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="6" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="7" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="8" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="9" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="96sp"
+ android:text="10" />
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/ui/ui-core/api/0.1.0-dev16.txt b/ui/ui-core/api/0.1.0-dev16.txt
index 0c120f5..e8262d5 100644
--- a/ui/ui-core/api/0.1.0-dev16.txt
+++ b/ui/ui-core/api/0.1.0-dev16.txt
@@ -750,8 +750,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1858,12 +1856,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 0c120f5..e8262d5 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -750,8 +750,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1858,12 +1856,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
index 0c120f5..e8262d5 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
@@ -750,8 +750,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1858,12 +1856,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 0c120f5..e8262d5 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -750,8 +750,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1858,12 +1856,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/api/restricted_0.1.0-dev16.txt b/ui/ui-core/api/restricted_0.1.0-dev16.txt
index a6abfad..0780958 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev16.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev16.txt
@@ -802,8 +802,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1910,12 +1908,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index a6abfad..0780958 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -802,8 +802,6 @@
public final class PointerEvent {
ctor public PointerEvent(java.util.List<androidx.ui.core.PointerInputChange> changes);
- method public java.util.List<androidx.ui.core.PointerInputChange> component1();
- method public androidx.ui.core.PointerEvent copy(java.util.List<androidx.ui.core.PointerInputChange> changes);
method public java.util.List<androidx.ui.core.PointerInputChange> getChanges();
}
@@ -1910,12 +1908,7 @@
public final class HitPathTrackerKt {
}
- public final class PointerInputEventData {
- method public long component1();
- method public androidx.ui.core.PointerInputData component2();
- method public androidx.ui.core.pointerinput.PointerInputEventData copy-tII9_pY(long id, androidx.ui.core.PointerInputData pointerInputData);
- method public long getId();
- method public androidx.ui.core.PointerInputData getPointerInputData();
+ public final class MotionEventAdapterKt {
}
public final class PointerInputEventProcessorKt {
diff --git a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
similarity index 98%
rename from ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
rename to ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
index 9c94849..460f820 100644
--- a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
@@ -21,7 +21,6 @@
import androidx.ui.core.Constraints
import androidx.ui.core.CustomEvent
import androidx.ui.core.CustomEventDispatcher
-import androidx.ui.core.InternalPointerEvent
import androidx.ui.core.LayoutCoordinates
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerId
@@ -30,11 +29,11 @@
import androidx.ui.core.consumeDownChange
import androidx.ui.core.consumePositionChange
import androidx.ui.core.positionChange
+import androidx.ui.geometry.Offset
import androidx.ui.testutils.down
import androidx.ui.testutils.moveTo
import androidx.ui.unit.IntSize
import androidx.ui.unit.PxBounds
-import androidx.ui.geometry.Offset
import androidx.ui.unit.milliseconds
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any
@@ -208,7 +207,7 @@
@Test
fun dispatchChanges_noNodes_doesNotCrash() {
- hitPathTracker.dispatchChanges(pointerEventOf(down(0)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(0)))
}
@Test
@@ -216,7 +215,7 @@
val pif: PointerInputFilter = PointerInputFilterMock()
hitPathTracker.addHitPath(PointerId(13), listOf(pif))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
// Verify call count
verify(pif, times(5)).onPointerEvent(any(), any(), any())
@@ -237,7 +236,7 @@
val pif3: PointerInputFilter = PointerInputFilterMock()
hitPathTracker.addHitPath(PointerId(13), listOf(pif1, pif2, pif3))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
// Verify call count
verify(pif1, times(5)).onPointerEvent(any(), any(), any())
@@ -270,7 +269,7 @@
val pif3: PointerInputFilter = PointerInputFilterMock()
hitPathTracker.addHitPath(PointerId(13), listOf(pif1, pif2, pif3))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
// Verify call count
verify(pif1, times(5)).onPointerEvent(any(), any(), any())
@@ -323,7 +322,7 @@
val event2 = down(5).moveTo(10.milliseconds, 7f, 9f)
hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
// Verify call count
@@ -389,7 +388,7 @@
val event2 = down(5).moveTo(10.milliseconds, 7f, 9f)
hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
// Verify call count
@@ -462,7 +461,7 @@
val event2 = down(5).moveTo(10.milliseconds, 7f, 9f)
hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
// Verify call count
@@ -538,9 +537,9 @@
@Test
fun dispatchChanges_noNodes_nothingChanges() {
- val (result, _) = hitPathTracker.dispatchChanges(pointerEventOf(down(5)))
+ val (result, _) = hitPathTracker.dispatchChanges(internalPointerEventOf(down(5)))
- assertThat(result).isEqualTo(pointerEventOf(down(5)))
+ assertThat(result.changes.values.first()).isEqualTo(down(5))
}
@Test
@@ -553,9 +552,9 @@
)
hitPathTracker.addHitPath(PointerId(13), listOf(pif1))
- val (result, _) = hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ val (result, _) = hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
- assertThat(result).isEqualTo(pointerEventOf(down(13).consumeDownChange()))
+ assertThat(result.changes.values.first()).isEqualTo(down(13).consumeDownChange())
}
@Test
@@ -605,7 +604,7 @@
hitPathTracker.addHitPath(PointerId(13), listOf(pif1, pif2, pif3))
val change = down(13).moveTo(10.milliseconds, 0f, 130f)
- val (result, _) = hitPathTracker.dispatchChanges(pointerEventOf(change))
+ val (result, _) = hitPathTracker.dispatchChanges(internalPointerEventOf(change))
verify(pif1).onPointerInput(
eq(listOf(change)), eq(PointerEventPass.InitialDown), any()
@@ -635,15 +634,8 @@
eq(PointerEventPass.PreUp),
any()
)
- assertThat(result)
- .isEqualTo(
- pointerEventOf(
- change.consumePositionChange(
- 0f,
- 126f
- )
- )
- ) // 2 + 4 + 8 + 16 + 32 + 64
+ assertThat(result.changes.values.first())
+ .isEqualTo(change.consumePositionChange(0f, 126f)) // 2 + 4 + 8 + 16 + 32 + 64
}
@Test
@@ -710,7 +702,7 @@
val event2 = down(5).moveTo(10.milliseconds, 0f, -24f)
val (result, _) = hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
verify(pif1).onPointerInput(
@@ -819,7 +811,7 @@
val event2 = down(5).moveTo(10.milliseconds, 0f, -1000f)
val (result, _) = hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
verify(parent).onPointerInput(
@@ -905,7 +897,7 @@
val event2 = down(5).moveTo(10.milliseconds, 0f, -1000f)
val (result, _) = hitPathTracker.dispatchChanges(
- pointerEventOf(event1, event2)
+ internalPointerEventOf(event1, event2)
)
verify(child1).onPointerInput(
@@ -2669,7 +2661,7 @@
@Test
fun dispatchChanges_noNodes_reportsWasDispatchedToNothing() {
- val (_, hitSomething) = hitPathTracker.dispatchChanges(pointerEventOf(down(0)))
+ val (_, hitSomething) = hitPathTracker.dispatchChanges(internalPointerEventOf(down(0)))
assertThat(hitSomething).isFalse()
}
@@ -2678,7 +2670,7 @@
val pif: PointerInputFilter = PointerInputFilterMock()
hitPathTracker.addHitPath(PointerId(13), listOf(pif))
- val (_, hitSomething) = hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ val (_, hitSomething) = hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
assertThat(hitSomething).isTrue()
}
@@ -2688,7 +2680,7 @@
val pif: PointerInputFilter = PointerInputFilterMock()
hitPathTracker.addHitPath(PointerId(13), listOf(pif))
- val (_, hitSomething) = hitPathTracker.dispatchChanges(pointerEventOf(down(69)))
+ val (_, hitSomething) = hitPathTracker.dispatchChanges(internalPointerEventOf(down(69)))
assertThat(hitSomething).isFalse()
}
@@ -2965,7 +2957,7 @@
)
hitPathTracker.addHitPath(PointerId(13), listOf(pif))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
var passedRemovalPass = false
PointerEventPass.values().forEach {
@@ -3031,7 +3023,7 @@
)
hitPathTracker.addHitPath(PointerId(13), listOf(parentPif, childPif))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
val removalPassIsDown =
when (removalPass) {
@@ -3105,7 +3097,7 @@
)
hitPathTracker.addHitPath(PointerId(13), listOf(parentPif, childPif))
- hitPathTracker.dispatchChanges(pointerEventOf(down(13)))
+ hitPathTracker.dispatchChanges(internalPointerEventOf(down(13)))
val removalPassIsDown =
when (removalPass) {
@@ -3471,7 +3463,4 @@
override fun get(line: AlignmentLine): Int {
TODO("not implemented")
}
-}
-
-private fun pointerEventOf(vararg changes: PointerInputChange) =
- InternalPointerEvent(changes.toList().associateBy { it.id }.toMutableMap())
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/MotionEventAdapterTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/MotionEventAdapterTest.kt
index 1e59127..4f64868 100644
--- a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/MotionEventAdapterTest.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/MotionEventAdapterTest.kt
@@ -31,8 +31,6 @@
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-// TODO(shepshapard): Not sure how to test if a MotionEvent has been recycled.
-
@SmallTest
@RunWith(JUnit4::class)
class MotionEventAdapterTest {
@@ -58,7 +56,9 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
+ val platformEvent = pointerInputEvent.motionEvent
assertThat(uptime.nanoseconds).isEqualTo(2_894_000_000L)
assertThat(pointers).hasSize(1)
assertPointerInputEventData(
@@ -68,6 +68,7 @@
2967f,
5928f
)
+ assertThat(platformEvent).isSameInstanceAs(motionEvent)
}
@Test
@@ -94,7 +95,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(5_000_000L)
assertThat(pointers).hasSize(1)
assertPointerInputEventData(
@@ -130,7 +132,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(34_000_000L)
assertThat(uptime.nanoseconds).isEqualTo(34_000_000L)
assertThat(pointers).hasSize(1)
@@ -173,7 +176,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(4_000_000L)
assertThat(pointers).hasSize(2)
assertPointerInputEventData(
@@ -222,7 +226,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(4_000_000L)
assertThat(pointers).hasSize(2)
assertPointerInputEventData(
@@ -290,7 +295,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(12_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -365,7 +371,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(12_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -440,7 +447,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(12_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -512,7 +520,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(10_000_000L)
assertThat(pointers).hasSize(2)
assertPointerInputEventData(
@@ -577,7 +586,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(10_000_000L)
assertThat(pointers).hasSize(2)
assertPointerInputEventData(
@@ -642,7 +652,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(10_000_000L)
assertThat(pointers).hasSize(2)
assertPointerInputEventData(
@@ -728,7 +739,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(20_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -821,7 +833,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(20_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -914,7 +927,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(20_000_000L)
assertThat(pointers).hasSize(3)
assertPointerInputEventData(
@@ -1102,7 +1116,8 @@
val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
assertThat(pointerInputEvent).isNotNull()
- val (uptime, pointers) = pointerInputEvent!!
+ val uptime = pointerInputEvent!!.uptime
+ val pointers = pointerInputEvent.pointers
assertThat(uptime.nanoseconds).isEqualTo(0L)
assertThat(pointers).hasSize(1)
assertPointerInputEventData(pointers[0], PointerId(0), true, 1f, 2f)
@@ -1147,7 +1162,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent1)
motionEventAdapter.convertToPointerInputEvent(motionEvent2)
- assertThat(motionEventAdapter.intIdToPointerIdMap).isEmpty()
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).isEmpty()
}
@Test
@@ -1178,7 +1193,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent1)
motionEventAdapter.convertToPointerInputEvent(motionEvent2)
- assertThat(motionEventAdapter.intIdToPointerIdMap).containsExactlyEntriesIn(
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).containsExactlyEntriesIn(
mapOf(
2 to PointerId(0),
5 to PointerId(1)
@@ -1229,7 +1244,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent2)
motionEventAdapter.convertToPointerInputEvent(motionEvent3)
- assertThat(motionEventAdapter.intIdToPointerIdMap).containsExactlyEntriesIn(
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).containsExactlyEntriesIn(
mapOf(2 to PointerId(0))
)
}
@@ -1277,7 +1292,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent2)
motionEventAdapter.convertToPointerInputEvent(motionEvent3)
- assertThat(motionEventAdapter.intIdToPointerIdMap).containsExactlyEntriesIn(
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).containsExactlyEntriesIn(
mapOf(5 to PointerId(1))
)
}
@@ -1334,7 +1349,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent3)
motionEventAdapter.convertToPointerInputEvent(motionEvent4)
- assertThat(motionEventAdapter.intIdToPointerIdMap).isEmpty()
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).isEmpty()
}
@Test
@@ -1379,7 +1394,7 @@
motionEventAdapter.convertToPointerInputEvent(motionEvent2)
motionEventAdapter.convertToPointerInputEvent(motionEvent3)
- assertThat(motionEventAdapter.intIdToPointerIdMap).isEmpty()
+ assertThat(motionEventAdapter.motionEventToComposePointerIdMap).isEmpty()
}
@Test
@@ -1399,6 +1414,77 @@
assertThat(motionEvent.x).isEqualTo(13f)
assertThat(motionEvent.y).isEqualTo(104f)
}
+
+ @Test
+ fun convertToPointerInputEvent_1PointerActionDown_includesMotionEvent() {
+ val motionEvent = MotionEvent(
+ 2894,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(8290)),
+ arrayOf(PointerCoords(2967f, 5928f))
+ )
+
+ val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
+ assertThat(pointerInputEvent).isNotNull()
+
+ assertThat(pointerInputEvent!!.motionEvent).isSameInstanceAs(motionEvent)
+ }
+
+ @Test
+ fun convertToPointerInputEvent_1pointerActionMove_includesMotionEvent() {
+ motionEventAdapter.convertToPointerInputEvent(
+ MotionEvent(
+ 1,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(2)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ )
+ val motionEvent = MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(2)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
+
+ val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
+ assertThat(pointerInputEvent).isNotNull()
+
+ assertThat(pointerInputEvent!!.motionEvent).isSameInstanceAs(motionEvent)
+ }
+
+ @Test
+ fun convertToPointerInputEvent_1pointerActionUp_includesMotionEvent() {
+ motionEventAdapter.convertToPointerInputEvent(
+ MotionEvent(
+ 10,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(46)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ )
+ val motionEvent = MotionEvent(
+ 34,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(46)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val pointerInputEvent = motionEventAdapter.convertToPointerInputEvent(motionEvent)
+ assertThat(pointerInputEvent).isNotNull()
+
+ assertThat(pointerInputEvent!!.motionEvent).isSameInstanceAs(motionEvent)
+ }
}
// Private helper functions
diff --git a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
similarity index 97%
rename from ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
rename to ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
index 491bfa3..428c3e2 100644
--- a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
@@ -17,9 +17,14 @@
package androidx.ui.core.pointerinput
import androidx.test.filters.SmallTest
+import androidx.ui.core.Constraints
import androidx.ui.core.ConsumedData
import androidx.ui.core.ExperimentalLayoutNodeApi
+import androidx.ui.core.LayoutDirection
import androidx.ui.core.LayoutNode
+import androidx.ui.core.LayoutNodeWrapper
+import androidx.ui.core.Measurable
+import androidx.ui.core.MeasureScope
import androidx.ui.core.Modifier
import androidx.ui.core.Owner
import androidx.ui.core.PointerEventPass
@@ -32,12 +37,15 @@
import androidx.ui.unit.IntOffset
import androidx.ui.unit.IntSize
import androidx.ui.unit.Uptime
-import androidx.ui.unit.minus
import androidx.ui.unit.milliseconds
+import androidx.ui.unit.minus
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.any
+import com.nhaarman.mockitokotlin2.doAnswer
+import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.inOrder
+import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.reset
import com.nhaarman.mockitokotlin2.spy
@@ -2650,13 +2658,15 @@
}
abstract class TestOwner : Owner {
- var position = IntOffset.Origin
+ var position: IntOffset? = null
@ExperimentalLayoutNodeApi
override val root: LayoutNode
get() = LayoutNode()
- override fun calculatePosition() = position
+ override fun calculatePosition(): IntOffset {
+ return position ?: IntOffset.Origin
+ }
}
open class TestPointerInputFilter(
@@ -2675,4 +2685,45 @@
}
private class PointerInputModifierImpl(override val pointerInputFilter: PointerInputFilter) :
- PointerInputModifier
\ No newline at end of file
+ PointerInputModifier
+
+@OptIn(ExperimentalLayoutNodeApi::class)
+private fun LayoutNode(x: Int, y: Int, x2: Int, y2: Int, modifier: Modifier = Modifier) =
+ LayoutNode().apply {
+ this.modifier = modifier
+ measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks("not supported") {
+ override fun measure(
+ measureScope: MeasureScope,
+ measurables: List<Measurable>,
+ constraints: Constraints,
+ layoutDirection: LayoutDirection
+ ): MeasureScope.MeasureResult =
+ measureScope.layout(x2 - x, y2 - y) {}
+ }
+ attach(mockOwner())
+ remeasure(Constraints(), layoutDirection)
+ var wrapper: LayoutNodeWrapper? = outerLayoutNodeWrapper
+ while (wrapper != null) {
+ wrapper.measureResult = innerLayoutNodeWrapper.measureResult
+ wrapper = (wrapper as? LayoutNodeWrapper)?.wrapped
+ }
+ place(x, y)
+ detach()
+ }
+
+@ExperimentalLayoutNodeApi
+private fun mockOwner(
+ position: IntOffset = IntOffset.Origin,
+ targetRoot: LayoutNode = LayoutNode()
+): Owner =
+ @Suppress("UNCHECKED_CAST")
+ mock {
+ on { calculatePosition() } doReturn position
+ on { root } doReturn targetRoot
+ on { observeMeasureModelReads(any(), any()) } doAnswer {
+ (it.arguments[1] as () -> Unit).invoke()
+ }
+ on { observeLayoutModelReads(any(), any()) } doAnswer {
+ (it.arguments[1] as () -> Unit).invoke()
+ }
+ }
\ No newline at end of file
diff --git a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/TestUtils.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/TestUtils.kt
similarity index 72%
rename from ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/TestUtils.kt
rename to ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/TestUtils.kt
index 3cb174d..a29b1e2 100644
--- a/ui/ui-core/src/test/kotlin/androidx/ui/core/pointerinput/TestUtils.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/core/pointerinput/TestUtils.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * Copyright 2020 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.
@@ -16,6 +16,7 @@
package androidx.ui.core.pointerinput
+import androidx.ui.core.InternalPointerEvent
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerId
import androidx.ui.core.PointerInputChange
@@ -32,7 +33,7 @@
* the processing of incoming [PointerInputChange]s.
*/
open class StubPointerInputHandler(
- var modifyBlock: PointerInputHandler? = null
+ private var modifyBlock: PointerInputHandler? = null
) : PointerInputHandler {
override fun invoke(
p1: List<PointerInputChange>,
@@ -61,10 +62,20 @@
): PointerInputEvent {
return PointerInputEvent(
uptime,
- listOf(PointerInputEventData(id, uptime, position, down))
+ listOf(PointerInputEventData(id, uptime, position, down)),
+ MotionEventDouble
)
}
+internal fun PointerInputEvent(
+ uptime: Uptime,
+ pointers: List<PointerInputEventData>
+) = PointerInputEvent(
+ uptime,
+ pointers,
+ MotionEventDouble
+ )
+
internal fun catchThrowable(lambda: () -> Unit): Throwable? {
var exception: Throwable? = null
@@ -75,4 +86,14 @@
}
return exception
-}
\ No newline at end of file
+}
+
+internal fun internalPointerEventOf(vararg changes: PointerInputChange) =
+ InternalPointerEvent(changes.toList().associateBy { it.id }.toMutableMap(), MotionEventDouble)
+
+/**
+ * To be used to construct types that require a MotionEvent but where no details of the MotionEvent
+ * are actually needed.
+ */
+private val MotionEventDouble = android.view.MotionEvent.obtain(0L, 0L,
+ android.view.MotionEvent.ACTION_DOWN, 0f, 0f, 0)
\ No newline at end of file
diff --git a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterIntegrationTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterIntegrationTest.kt
new file mode 100644
index 0000000..15f5c6a
--- /dev/null
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterIntegrationTest.kt
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2020 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 androidx.ui.node
+
+import android.content.Context
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_UP
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.compose.Recomposer
+import androidx.compose.foundation.Box
+import androidx.test.filters.MediumTest
+import androidx.ui.core.DensityAmbient
+import androidx.ui.core.setContent
+import androidx.ui.framework.test.TestActivity
+import androidx.ui.test.android.AndroidComposeTestRule
+import androidx.ui.unit.dp
+import androidx.ui.viewinterop.AndroidView
+import com.nhaarman.mockitokotlin2.clearInvocations
+import com.nhaarman.mockitokotlin2.mock
+import com.nhaarman.mockitokotlin2.never
+import com.nhaarman.mockitokotlin2.times
+import com.nhaarman.mockitokotlin2.verify
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+// Tests that pointer offsets are correct when a pointer is dispatched from Android through
+// Compose and back into Android and each layer offsets the pointer during dispatch.
+@MediumTest
+@RunWith(JUnit4::class)
+class PointerInteropFilterIntegrationTest {
+
+ private lateinit var five: View
+ private val theHitListener: () -> Unit = mock()
+
+ @get:Rule
+ val composeTestRule = AndroidComposeTestRule<TestActivity>()
+
+ @Before
+ fun setup() {
+ composeTestRule.activityRule.scenario.onActivity { activity ->
+
+ // one: Android View that is the touch target, inside
+ // two: Android View with 1x2 padding, inside
+ // three: Compose Box with 2x12 padding, inside
+ // four: Android View with 3x13 padding, inside
+ // five: Android View with 4x14 padding
+ //
+ // With all of the padding, "one" is at 10 x 50 relative to "five" and the tests
+ // dispatch MotionEvents to "five".
+
+ val {
+ layoutParams = ViewGroup.LayoutParams(1, 1)
+ hitListener = theHitListener
+ }
+
+ val two = FrameLayout(activity).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ setPadding(1, 11, 0, 0)
+ addView(one)
+ }
+
+ val four = FrameLayout(activity).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ setPadding(3, 13, 0, 0)
+ setContent(Recomposer.current()) {
+ with(DensityAmbient.current) {
+ // Box is "three"
+ Box(
+ paddingStart = (2f / density).dp,
+ paddingTop = (12f / density).dp
+ ) {
+ AndroidView(two)
+ }
+ }
+ }
+ }
+
+ five = FrameLayout(activity).apply {
+ layoutParams = ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
+ )
+ setPadding(4, 14, 0, 0)
+ addView(four)
+ }
+
+ activity.setContentView(five)
+ }
+ }
+
+ @Test
+ fun uiClick_inside_hits() {
+ uiClick(10, 50, true)
+ }
+
+ @Test
+ fun uiClick_justOutside_misses() {
+ uiClick(9, 50, false)
+ uiClick(10, 49, false)
+ uiClick(11, 50, false)
+ uiClick(10, 51, false)
+ }
+
+ // Gets reused to should always clean up state.
+ private fun uiClick(x: Int, y: Int, hits: Boolean) {
+ clearInvocations(theHitListener)
+
+ composeTestRule.activityRule.scenario.onActivity {
+ val down =
+ MotionEvent.obtain(
+ 0L,
+ 0L,
+ ACTION_DOWN,
+ x.toFloat(),
+ y.toFloat(),
+ 0
+ )
+ val up =
+ MotionEvent.obtain(
+ 0L,
+ 1L,
+ ACTION_UP,
+ x.toFloat(),
+ y.toFloat(),
+ 0
+ )
+ five.dispatchTouchEvent(down)
+ five.dispatchTouchEvent(up)
+ }
+
+ if (hits) {
+ verify(theHitListener, times(2)).invoke()
+ } else {
+ verify(theHitListener, never()).invoke()
+ }
+ }
+}
+
+private class CustomView(context: Context) : View(context) {
+ lateinit var hitListener: () -> Unit
+
+ override fun onTouchEvent(event: MotionEvent?): Boolean {
+ hitListener()
+ return true
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterTest.kt
index 2954242..db7a1c3 100644
--- a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterTest.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropFilterTest.kt
@@ -20,20 +20,25 @@
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_CANCEL
import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
import android.view.MotionEvent.TOOL_TYPE_UNKNOWN
import androidx.activity.ComponentActivity
import androidx.test.filters.SmallTest
+import androidx.ui.core.PointerEvent
import androidx.ui.core.PointerEventPass
+import androidx.ui.core.PointerInputChange
import androidx.ui.core.consumeAllChanges
import androidx.ui.core.consumeDownChange
import androidx.ui.test.android.AndroidComposeTestRule
import androidx.ui.testutils.consume
import androidx.ui.testutils.down
-import androidx.ui.testutils.invokeOverAllPasses
-import androidx.ui.testutils.invokeOverPasses
import androidx.ui.testutils.moveBy
import androidx.ui.testutils.moveTo
import androidx.ui.testutils.up
+import androidx.ui.unit.IntSize
import androidx.ui.unit.milliseconds
import androidx.ui.viewinterop.AndroidViewHolder
import com.google.common.truth.Truth.assertThat
@@ -63,7 +68,7 @@
// Verification of correct MotionEvents being dispatched (when no events are cancel)
@Test
- fun onPointerInput_1PointerDown_correctMotionEventDispatched() {
+ fun onPointerEvent_1PointerDown_correctMotionEventDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
val expected =
MotionEvent(
@@ -71,43 +76,67 @@
ACTION_DOWN,
1,
0,
- arrayOf(PointerProperties(1)),
+ arrayOf(PointerProperties(0)),
arrayOf(PointerCoords(3f, 4f))
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- assertEquals(mockViewGroup.dispatchedMotionEvents[0], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[0]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_1PointerUp_correctMotionEventDispatched() {
+ fun onPointerEvent_1PointerUp_correctMotionEventDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val downMotionEvent =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val up = down.up(5.milliseconds)
val expected =
MotionEvent(
5,
- MotionEvent.ACTION_UP,
+ ACTION_UP,
1,
0,
- arrayOf(PointerProperties(1)),
+ arrayOf(PointerProperties(0)),
arrayOf(PointerCoords(3f, 4f))
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = downMotionEvent)
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersDown_correctMotionEventDispatched() {
+ fun onPointerEvent_2PointersDown_correctMotionEventDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val downMotionEvent =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
@@ -115,12 +144,12 @@
val expected =
MotionEvent(
7,
- MotionEvent.ACTION_POINTER_DOWN,
+ ACTION_POINTER_DOWN,
2,
1,
arrayOf(
- PointerProperties(1),
- PointerProperties(8)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(3f, 4f),
@@ -128,24 +157,37 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = downMotionEvent)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, bDown, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersDownAllPassesAltOrder_correctMotionEventDispatched() {
+ fun onPointerEvent_2PointersDownAllPassesAltOrder_correctMotionEventDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val downMotionEvent =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
@@ -153,52 +195,61 @@
val expected =
MotionEvent(
7,
- MotionEvent.ACTION_POINTER_DOWN,
+ ACTION_POINTER_DOWN,
2,
0,
arrayOf(
- PointerProperties(8),
- PointerProperties(1)
+ PointerProperties(1),
+ PointerProperties(0)
),
arrayOf(
PointerCoords(10f, 11f),
PointerCoords(3f, 4f)
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = downMotionEvent)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bDown, aMove)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bDown, aMove, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2Pointers1Up_correctMotionEventDispatched() {
+ fun onPointerEvent_2Pointers1Up_correctMotionEventDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
-
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
- val bDown = down(8, 7.milliseconds, 10f, 11f)
-
- val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
- val bUp = bDown.up(13.milliseconds)
-
- val expected =
+ val motionEvent1 =
MotionEvent(
- 13,
- MotionEvent.ACTION_POINTER_UP,
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
+ val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
2,
1,
arrayOf(
- PointerProperties(1),
- PointerProperties(8)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(3f, 4f),
@@ -206,40 +257,88 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
-
- // Act
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bUp)
-
- // Assert
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
- }
-
- @Test
- fun onPointerInput_2Pointers1UpAllPassesAltOrder_correctMotionEventDispatched() {
-
- // Arrange
-
- val aDown = down(1, 2.milliseconds, 3f, 4f)
-
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
- val bDown = down(8, 7.milliseconds, 10f, 11f)
-
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
val bUp = bDown.up(13.milliseconds)
val expected =
MotionEvent(
13,
- MotionEvent.ACTION_POINTER_UP,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(10f, 11f)
+ )
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+
+ // Act
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = expected)
+ )
+
+ // Assert
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
+ }
+
+ @Test
+ fun onPointerEvent_2Pointers1UpAllPassesAltOrder_correctMotionEventDispatched() {
+
+ // Arrange
+
+ val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
+ val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(10f, 11f)
+ )
+ )
+
+ val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
+ val bUp = bDown.up(13.milliseconds)
+ val expected =
+ MotionEvent(
+ 13,
+ ACTION_POINTER_UP,
2,
0,
arrayOf(
- PointerProperties(8),
+ PointerProperties(0),
PointerProperties(1)
),
arrayOf(
@@ -248,49 +347,92 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bUp, aMove2)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bUp, aMove2, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_1PointerMove_correctMotionEventDispatched() {
+ fun onPointerEvent_1PointerMove_correctMotionEventDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val move = down.moveTo(7.milliseconds, 8f, 9f)
val expected =
MotionEvent(
7,
- MotionEvent.ACTION_MOVE,
+ ACTION_MOVE,
1,
0,
- arrayOf(PointerProperties(1)),
+ arrayOf(PointerProperties(0)),
arrayOf(PointerCoords(8f, 9f))
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersMove_correctMotionEventDispatched() {
+ fun onPointerEvent_2PointersMove_correctMotionEventDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 0,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(13f, 14f),
+ PointerCoords(3f, 4f)
+ )
+ )
val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
val bMove1 = bDown.moveTo(15.milliseconds, 18f, 19f)
@@ -298,12 +440,12 @@
val expected =
MotionEvent(
15,
- MotionEvent.ACTION_MOVE,
+ ACTION_MOVE,
2,
0,
arrayOf(
- PointerProperties(1),
- PointerProperties(11)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(8f, 9f),
@@ -311,40 +453,70 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bMove1)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove1, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersMoveAltOrder_correctMotionEventDispatched() {
+ fun onPointerEvent_2PointersMoveAltOrder_correctMotionEventDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
-
- val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
- val bMove1 = bDown.moveTo(15.milliseconds, 18f, 19f)
-
- val expected =
+ val motionEvent2 =
MotionEvent(
- 15,
- MotionEvent.ACTION_MOVE,
+ 7,
+ ACTION_POINTER_DOWN,
2,
0,
arrayOf(
- PointerProperties(11),
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(13f, 14f),
+ PointerCoords(3f, 4f)
+ )
+ )
+
+ val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
+ val bMove1 = bDown.moveTo(15.milliseconds, 18f, 19f)
+ val expected =
+ MotionEvent(
+ 15,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(
+ PointerProperties(0),
PointerProperties(1)
),
arrayOf(
@@ -353,24 +525,40 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bMove1, aMove2)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bMove1, aMove2, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
}
// Verification of correct cancel events being dispatched
@Test
- fun onPointerInput_1PointerUpConsumed_correctCancelDispatched() {
+ fun onPointerEvent_1PointerUpConsumed_correctCancelDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val upConsumed = down.up(5.milliseconds).consumeDownChange()
val expected =
MotionEvent(
@@ -378,27 +566,39 @@
ACTION_CANCEL,
1,
0,
- arrayOf(PointerProperties(1)),
+ arrayOf(PointerProperties(0)),
arrayOf(PointerCoords(3f, 4f))
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(upConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(upConsumed, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersDown2ndDownConsumed_correctCancelDispatched() {
+ fun onPointerEvent_2PointersDown2ndDownConsumed_correctCancelDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDownConsumed = down(8, 7.milliseconds, 10f, 11f).consumeDownChange()
-
val expected =
MotionEvent(
7,
@@ -406,8 +606,8 @@
2,
0,
arrayOf(
- PointerProperties(1),
- PointerProperties(8)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(3f, 4f),
@@ -415,32 +615,58 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove, bDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, bDownConsumed, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2Pointers1UpConsumed_correctCancelDispatched() {
+ fun onPointerEvent_2Pointers1UpConsumed_correctCancelDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(10f, 11f)
+ )
+ )
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
val bUpConsumed = bDown.up(13.milliseconds).consumeDownChange()
-
val expected =
MotionEvent(
13,
@@ -448,8 +674,8 @@
2,
0,
arrayOf(
- PointerProperties(1),
- PointerProperties(8)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(3f, 4f),
@@ -457,23 +683,38 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bUpConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUpConsumed, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_1PointerMoveConsumed_correctCancelDispatched() {
+ fun onPointerEvent_1PointerMoveConsumed_correctCancelDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val moveConsumed = down.moveTo(7.milliseconds, 8f, 9f).consume(1f, 0f)
val expected =
MotionEvent(
@@ -481,26 +722,54 @@
ACTION_CANCEL,
1,
0,
- arrayOf(PointerProperties(1)),
- arrayOf(PointerCoords(8f, 9f))
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(moveConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(moveConsumed, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- assertEquals(mockViewGroup.dispatchedMotionEvents[1], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[1]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_2PointersMoveConsumed_correctCancelDispatched() {
+ fun onPointerEvent_2PointersMoveConsumed_correctCancelDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(13f, 14f)
+ )
+ )
val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
val bMoveConsumed = bDown.moveTo(15.milliseconds, 18f, 19f).consume(1f, 0f)
@@ -512,8 +781,8 @@
2,
0,
arrayOf(
- PointerProperties(1),
- PointerProperties(11)
+ PointerProperties(0),
+ PointerProperties(1)
),
arrayOf(
PointerCoords(8f, 9f),
@@ -521,131 +790,399 @@
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bMoveConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMoveConsumed, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- assertEquals(mockViewGroup.dispatchedMotionEvents[2], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[2]).isSameInstanceAs(expected)
}
// Verification of no longer dispatching to children once we have consumed events
@Test
- fun onPointerInput_downConsumed_nothingDispatched() {
+ fun onPointerEvent_downConsumed_nothingDispatched() {
val downConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(downConsumed)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(downConsumed, motionEvent = motionEvent1)
+ )
+
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_downConsumedThenMoveThenUp_nothingDispatched() {
+ fun onPointerEvent_downConsumedThenMoveThenUp_nothingDispatched() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val aMove = aDownConsumed.moveTo(5.milliseconds, 6f, 7f)
- val aUp = aMove.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
+ val aUp = aMove.up(10.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent3)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ConsumedThenDown2ThenMove2ThenUp2_nothingDispatched() {
+ fun onPointerEvent_down1ConsumedThenDown2ThenMove2ThenUp2_nothingDispatched() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
- val aMove1 = aDownConsumed.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove1 = aDownConsumed.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
+
val aMove2 = aDownConsumed.moveTo(21.milliseconds, 6f, 7f)
val bMove = bDown.moveTo(21.milliseconds, 22f, 23f)
+ val motionEvent3 =
+ MotionEvent(
+ 21,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(6f, 7f), PointerCoords(22f, 23f))
+ )
+
val aMove3 = aDownConsumed.moveTo(31.milliseconds, 6f, 7f)
val bUp = bMove.up(31.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(6f, 7f), PointerCoords(22f, 23f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bMove)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove3, bUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove3, bUp, motionEvent = motionEvent4)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ConsumedThenDown2ThenUp1ThenDown3_nothingDispatched() {
+ fun onPointerEvent_down1ConsumedThenDown2ThenUp1ThenDown3_nothingDispatched() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDownConsumed.moveTo(11.milliseconds, 3f, 4f)
+ val aMove1 = aDownConsumed.moveTo(22.milliseconds, 3f, 4f)
val bDown = down(21, 22.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 22,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aUp = aMove1.up(31.milliseconds)
val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val bMove2 = bMove1.moveTo(41.milliseconds, 23f, 24f)
val cDown = down(51, 41.milliseconds, 52f, 53f)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(1), PointerProperties(0)),
+ arrayOf(PointerCoords(23f, 24f), PointerCoords(52f, 53f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bMove2, cDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bMove2, cDown, motionEvent = motionEvent4)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_downThenMoveConsumedThenMoveThenUp_afterConsumeNoDispatch() {
+ fun onPointerEvent_downThenMoveConsumedThenMoveThenUp_afterConsumeNoDispatch() {
val down = down(1, 2.milliseconds, 3f, 4f)
- val move1Consumed = down.moveTo(5.milliseconds, 6f, 7f).consume(0f, 1f)
- val move2 = move1Consumed.moveTo(10.milliseconds, 11f, 12f)
- val up = move2.up(10.milliseconds)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move1Consumed)
+ val move1Consumed = down.moveTo(5.milliseconds, 6f, 7f).consume(0f, 1f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 47f))
+ )
+ val move2 = move1Consumed.moveTo(10.milliseconds, 11f, 12f)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(11f, 12f))
+ )
+ val up = move2.up(15.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 15,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(11f, 12f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move1Consumed, motionEvent = motionEvent2)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move2)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move2, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent4)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ThenDown2ConsumedThenMoveThenUp1ThenUp2_afterConsumeNoDispatch() {
+ fun onPointerEvent_down1ThenDown2ConsumedThenMoveThenUp1ThenUp2_afterConsumeNoDispatch() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDownConsumed = down(21, 11.milliseconds, 23f, 24f).consumeDownChange()
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aMove2 = aMove1.moveTo(31.milliseconds, 31f, 32f)
val bMove = bDownConsumed.moveTo(31.milliseconds, 33f, 34f)
+ val motionEvent3 =
+ MotionEvent(
+ 11,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
- val aMove3 = aMove2.moveTo(41.milliseconds, 42f, 43f)
+ val aMove3 = aMove2.moveTo(41.milliseconds, 31f, 32f)
val bUp = bMove.up(41.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
val aUp = aMove3.up(51.milliseconds)
+ val motionEvent5 =
+ MotionEvent(
+ 51,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(31f, 32f))
+ )
// Act
- val pointerInputHandler = pointerInteropFilter.pointerInputFilter::onPointerInput
- pointerInputHandler.invokeOverAllPasses(aDown)
- pointerInputHandler.invokeOverAllPasses(aMove1, bDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDownConsumed, motionEvent = motionEvent2)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInputHandler.invokeOverAllPasses(aMove2, bMove)
- pointerInputHandler.invokeOverAllPasses(aMove3, bUp)
- pointerInputHandler.invokeOverAllPasses(aUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove3, bUp, motionEvent = motionEvent4)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent5)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ConsumedThenUp1ThenDown2_finalDownDispatched() {
+ fun onPointerEvent_down1ConsumedThenUp1ThenDown2_finalDownDispatched() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val aUp = aDownConsumed.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(
+ PointerProperties(0)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f)
+ )
+ )
+
val bDown = down(11, 12.milliseconds, 13f, 14f)
val expected =
MotionEvent(
@@ -654,109 +1191,236 @@
1,
0,
arrayOf(
- PointerProperties(11)
+ PointerProperties(0)
),
arrayOf(
PointerCoords(13f, 14f)
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bDown, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- assertEquals(mockViewGroup.dispatchedMotionEvents[0], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[0]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_down1ConsumedThenDown2ThenUp1ThenUp2ThenDown3_finalDownDispatched() {
+ fun onPointerEvent_down1ConsumedThenDown2ThenUp1ThenUp2ThenDown3_finalDownDispatched() {
// Arrange
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDownConsumed.moveTo(22.milliseconds, 3f, 4f)
val bDown = down(21, 22.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 22,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aUp = aMove1.up(31.milliseconds)
val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val bUp = bMove1.up(41.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(1)),
+ arrayOf(PointerCoords(23f, 24f))
+ )
val cDown = down(51, 52.milliseconds, 53f, 54f)
-
val expected =
MotionEvent(
52,
ACTION_DOWN,
1,
0,
- arrayOf(
- PointerProperties(51)
- ),
- arrayOf(
- PointerCoords(53f, 54f)
- )
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(53f, 54f))
)
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bUp)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(cDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bUp, motionEvent = motionEvent4)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(cDown, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- assertEquals(mockViewGroup.dispatchedMotionEvents[0], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[0]).isSameInstanceAs(expected)
}
// Verification no longer dispatching to children due to the child returning false for
// dispatchTouchEvent(...)
@Test
- fun onPointerInput_downViewRetsFalseThenMoveThenUp_noDispatchAfterRetFalse() {
+ fun onPointerEvent_downViewRetsFalseThenMoveThenUp_noDispatchAfterRetFalse() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val aMove = aDown.moveTo(5.milliseconds, 6f, 7f)
- val aUp = aMove.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 2,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
+
+ val aUp = aMove.up(10.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
+
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent3)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ViewRetsFalseThenDown2ThenMove2ThenUp2_noDispatchAfterRetFalse() {
+ fun onPointerEvent_down1ViewRetsFalseThenDown2ThenMove2ThenUp2_noDispatchAfterRetFalse() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(5.milliseconds, 6f, 7f)
+ val aMove1 = aDown.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
val aMove2 = aDown.moveTo(21.milliseconds, 6f, 7f)
val bMove = bDown.moveTo(21.milliseconds, 22f, 23f)
+ val motionEvent3 =
+ MotionEvent(
+ 21,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(6f, 7f), PointerCoords(22f, 23f))
+ )
val aMove3 = aDown.moveTo(31.milliseconds, 6f, 7f)
val bUp = bMove.up(31.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(6f, 7f), PointerCoords(22f, 23f))
+ )
mockViewGroup.returnValue = false
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bMove)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove3, bUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove3, bUp, motionEvent = motionEvent4)
+ )
// Assert
@@ -764,81 +1428,246 @@
}
@Test
- fun onPointerInput_down1ViewRetsFalseThenDown2ThenUp1ThenDown3_noDispatchAfterRetFalse() {
+ fun onPointerEvent_down1ViewRetsFalseThenDown2ThenUp1ThenDown3_noDispatchAfterRetFalse() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
-
- val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
- val bDown = down(21, 22.milliseconds, 23f, 24f)
-
- val aUp = aMove1.up(31.milliseconds)
- val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
-
- val bMove2 = bMove1.moveTo(41.milliseconds, 23f, 24f)
- val cDown = down(51, 41.milliseconds, 52f, 53f)
-
- mockViewGroup.returnValue = false
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bMove2, cDown)
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
- }
-
- @Test
- fun onPointerInput_downThenMoveViewRetsFalseThenMoveThenUp_noDispatchAfterRetFalse() {
- val down = down(1, 2.milliseconds, 3f, 4f)
- val move1 = down.moveTo(5.milliseconds, 6f, 7f)
- val move2 = move1.moveTo(10.milliseconds, 11f, 12f)
- val up = move2.up(10.milliseconds)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move1)
- mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move2)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
- }
-
- @Test
- fun onPointerInput_down1ThenDown2ViewRetsFalseThenMoveThenUp1ThenUp2_noDispatchAfterRetFalse() {
- // Arrange
-
- val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 2,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
+
+ val aUp = aMove1.up(31.milliseconds)
+ val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
+
+ val bMove2 = bMove1.moveTo(41.milliseconds, 23f, 24f)
+ val cDown = down(51, 41.milliseconds, 52f, 53f)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(1), PointerProperties(0)),
+ arrayOf(PointerCoords(23f, 24f), PointerCoords(52f, 53f))
+ )
+
+ mockViewGroup.returnValue = false
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ mockViewGroup.dispatchedMotionEvents.clear()
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bMove2, cDown, motionEvent = motionEvent4)
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
+ }
+
+ @Test
+ fun onPointerEvent_downThenMoveViewRetsFalseThenMoveThenUp_noDispatchAfterRetFalse() {
+ val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val move1 = down.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 47f))
+ )
+
+ val move2 = move1.moveTo(10.milliseconds, 11f, 12f)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(11f, 12f))
+ )
+
+ val up = move2.up(15.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 15,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(11f, 12f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ mockViewGroup.returnValue = false
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move1, motionEvent = motionEvent2)
+ )
+ mockViewGroup.dispatchedMotionEvents.clear()
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move2, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent4)
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
+ }
+
+ @Test
+ fun onPointerEvent_down1ThenDown2ViewRetsFalseThenMoveThenUp1ThenUp2_noDispatchAfterRetFalse() {
+ // Arrange
+
+ val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
+ val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 2,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aMove2 = aMove1.moveTo(31.milliseconds, 31f, 32f)
val bMove = bDown.moveTo(31.milliseconds, 33f, 34f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
- val aMove3 = aMove2.moveTo(41.milliseconds, 42f, 43f)
+ val aMove3 = aMove2.moveTo(41.milliseconds, 31f, 32f)
val bUp = bMove.up(41.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
val aUp = aMove3.up(51.milliseconds)
+ val motionEvent5 =
+ MotionEvent(
+ 51,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(31f, 32f))
+ )
// Act
- val pointerInputHandler = pointerInteropFilter.pointerInputFilter::onPointerInput
- pointerInputHandler.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- pointerInputHandler.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInputHandler.invokeOverAllPasses(aMove2, bMove)
- pointerInputHandler.invokeOverAllPasses(aMove3, bUp)
- pointerInputHandler.invokeOverAllPasses(aUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove3, bUp, motionEvent = motionEvent4)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent5)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
}
@Test
- fun onPointerInput_down1ViewRetsFalseThenUp1ThenDown2_finalDownDispatched() {
+ fun onPointerEvent_down1ViewRetsFalseThenUp1ThenDown2_finalDownDispatched() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val aUp = aDown.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val bDown = down(11, 12.milliseconds, 13f, 14f)
mockViewGroup.returnValue = false
val expected =
@@ -848,67 +1677,113 @@
1,
0,
arrayOf(
- PointerProperties(11)
+ PointerProperties(0)
),
arrayOf(
PointerCoords(13f, 14f)
)
)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bDown, motionEvent = expected)
+ )
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- assertEquals(mockViewGroup.dispatchedMotionEvents[0], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[0]).isSameInstanceAs(expected)
}
@Test
- fun onPointerInput_down1ViewRetsFalseThenDown2ThenUp1ThenUp2ThenDown3_finalDownDispatched() {
+ fun onPointerEvent_down1ViewRetsFalseThenDown2ThenUp1ThenUp2ThenDown3_finalDownDispatched() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aUp = aMove1.up(31.milliseconds)
val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val bUp = bMove1.up(41.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(1)),
+ arrayOf(PointerCoords(23f, 24f))
+ )
val cDown = down(51, 52.milliseconds, 53f, 54f)
-
- mockViewGroup.returnValue = false
-
val expected =
MotionEvent(
52,
ACTION_DOWN,
1,
0,
- arrayOf(
- PointerProperties(51)
- ),
- arrayOf(
- PointerCoords(53f, 54f)
- )
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(53f, 54f))
)
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ mockViewGroup.returnValue = false
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bUp)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(cDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bUp, motionEvent = motionEvent4)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(cDown, motionEvent = expected)
+ )
// Assert
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- assertEquals(mockViewGroup.dispatchedMotionEvents[0], expected)
+ assertThat(mockViewGroup.dispatchedMotionEvents[0]).isSameInstanceAs(expected)
}
// Verification of correct consumption due to the return value of View.dispatchTouchEvent(...).
@@ -916,75 +1791,166 @@
// be consumed should be consumed.
@Test
- fun onPointerInput_1PointerDownViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_1PointerDownViewRetsFalse_nothingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
mockViewGroup.returnValue = false
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- assertThat(actual).isEqualTo(down)
+ assertThat(actual.first()).isEqualTo(down)
}
@Test
- fun onPointerInput_1PointerDownViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_1PointerDownViewRetsTrue_everythingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
mockViewGroup.returnValue = true
val expected = down.consumeAllChanges()
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_1PointerUpViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_1PointerUpViewRetsFalse_nothingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val up = down.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
mockViewGroup.returnValue = true
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(up)
+ assertThat(actual.first()).isEqualTo(up)
}
@Test
- fun onPointerInput_1PointerUpViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_1PointerUpViewRetsTrue_everythingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val up = down.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val expected = up.consumeAllChanges()
mockViewGroup.returnValue = true
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_2PointersDownViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_2PointersDownViewRetsFalse_nothingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
// Act
mockViewGroup.returnValue = false
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove, bDown)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, bDown, motionEvent = motionEvent2)
+ )
// Assert
@@ -992,25 +1958,47 @@
}
@Test
- fun onPointerInput_2PointersDownViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_2PointersDownViewRetsTrue_everythingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove.consumeAllChanges(), bDown.consumeAllChanges())
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
// Act
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove, bDown)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, bDown, motionEvent = motionEvent2)
+ )
// Assert
@@ -1018,30 +2006,63 @@
}
@Test
- fun onPointerInput_2Pointers1UpViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_2Pointers1UpViewRetsFalse_nothingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
val bUp = bDown.up(13.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 13,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove2, bUp)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
mockViewGroup.returnValue = false
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3)
+ )
// Assert
@@ -1049,29 +2070,62 @@
}
@Test
- fun onPointerInput_2Pointers1UpViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_2Pointers1UpViewRetsTrue_everythingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
val bUp = bDown.up(13.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 13,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove2.consumeAllChanges(), bUp.consumeAllChanges())
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove2, bUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3)
+ )
// Assert
@@ -1079,58 +2133,147 @@
}
@Test
- fun onPointerInput_1PointerMoveViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_1PointerMoveViewRetsFalse_nothingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
mockViewGroup.returnValue = true
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(move)
+ assertThat(actual.first()).isEqualTo(move)
}
@Test
- fun onPointerInput_1PointerMoveViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_1PointerMoveViewRetsTrue_everythingConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
- val move = down.moveBy(7.milliseconds, 8f, 9f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
mockViewGroup.returnValue = true
val expected = move.consumeAllChanges()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_2PointersMoveViewRetsFalse_nothingConsumed() {
+ fun onPointerEvent_2PointersMoveViewRetsFalse_nothingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(13f, 14f)
+ )
+ )
val aMove2 = aMove1.moveBy(15.milliseconds, 8f, 9f)
val bMove1 = bDown.moveBy(15.milliseconds, 18f, 19f)
+ val motionEvent3 =
+ MotionEvent(
+ 15,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(8f, 9f),
+ PointerCoords(18f, 19f)
+ )
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove2, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
mockViewGroup.returnValue = false
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bMove1)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove1, motionEvent = motionEvent3)
+ )
// Assert
@@ -1138,29 +2281,74 @@
}
@Test
- fun onPointerInput_2PointersMoveViewRetsTrue_everythingConsumed() {
+ fun onPointerEvent_2PointersMoveViewRetsTrue_everythingConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(13f, 14f)
+ )
+ )
val aMove2 = aMove1.moveBy(15.milliseconds, 8f, 9f)
val bMove1 = bDown.moveBy(15.milliseconds, 18f, 19f)
+ val motionEvent3 =
+ MotionEvent(
+ 15,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(8f, 9f),
+ PointerCoords(18f, 19f)
+ )
+ )
mockViewGroup.returnValue = true
val expected = listOf(aMove2.consumeAllChanges(), bMove1.consumeAllChanges())
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bMove1)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove1, motionEvent = motionEvent3)
+ )
// Assert
@@ -1172,87 +2360,234 @@
// should be consumed).
@Test
- fun onPointerInput_downConsumedThenMove_noAdditionalConsumption() {
+ fun onPointerEvent_downConsumedThenMove_noAdditionalConsumption() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDownConsumed.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
mockViewGroup.returnValue = true
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(aMove)
+ assertThat(actual.first()).isEqualTo(aMove)
}
@Test
- fun onPointerInput_downConsumedThenUp_noAdditionalConsumption() {
+ fun onPointerEvent_downConsumedThenUp_noAdditionalConsumption() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
val aUp = aDownConsumed.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(
+ PointerProperties(0)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f)
+ )
+ )
mockViewGroup.returnValue = true
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(aUp)
+ assertThat(actual.first()).isEqualTo(aUp)
}
@Test
- fun onPointerInput_down1ConsumedThenDown2_noAdditionalConsumption() {
+ fun onPointerEvent_down1ConsumedThenDown2_noAdditionalConsumption() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
- val aMove1 = aDownConsumed.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val aMove1 = aDownConsumed.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
+
val expected = listOf(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove1, bDown)
-
- assertThat(actual).isEqualTo(expected)
- }
-
- @Test
- fun onPointerInput_down1ConsumedThenDown2ThenMove_noAdditionalConsumption() {
- val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
- val aMove1 = aDownConsumed.moveTo(5.milliseconds, 6f, 7f)
- val bDown = down(11, 5.milliseconds, 13f, 14f)
- val aMove2 = aDownConsumed.moveTo(21.milliseconds, 6f, 7f)
- val bMove = bDown.moveTo(21.milliseconds, 22f, 23f)
- val expected = listOf(aMove2, bMove)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(
- aMove2,
- bMove
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
)
assertThat(actual).isEqualTo(expected)
}
@Test
- fun onPointerInput_2Pointers1MoveConsumed_noAdditionalConsumption() {
+ fun onPointerEvent_down1ConsumedThenDown2ThenMove_noAdditionalConsumption() {
+ val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val aMove1 = aDownConsumed.moveTo(5.milliseconds, 3f, 4f)
+ val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
+ val aMove2 = aDownConsumed.moveTo(21.milliseconds, 6f, 7f)
+ val bMove = bDown.moveTo(21.milliseconds, 22f, 23f)
+ val motionEvent3 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(6f, 7f), PointerCoords(22f, 23f))
+ )
+ val expected = listOf(aMove2, bMove)
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
+
+ assertThat(actual).isEqualTo(expected)
+ }
+
+ @Test
+ fun onPointerEvent_2Pointers1MoveConsumed_noAdditionalConsumption() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(13f, 14f)
+ )
+ )
val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
val bMoveConsumed = bDown.moveTo(15.milliseconds, 18f, 19f).consume(1f, 0f)
+ val motionEvent3 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(8f, 9f),
+ PointerCoords(18f, 19f)
+ )
+ )
val expected = listOf(aMove2, bMoveConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bMoveConsumed)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMoveConsumed, motionEvent = motionEvent3)
+ )
// Assert
@@ -1260,24 +2595,57 @@
}
@Test
- fun onPointerInput_down1ThenDown2ConsumedThenMove_noAdditionalConsumption() {
+ fun onPointerEvent_down1ThenDown2ConsumedThenMove_noAdditionalConsumption() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDownConsumed = down(21, 11.milliseconds, 23f, 24f).consumeDownChange()
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aMove2 = aMove1.moveTo(31.milliseconds, 31f, 32f)
val bMove = bDownConsumed.moveTo(31.milliseconds, 33f, 34f)
+ val motionEvent3 =
+ MotionEvent(
+ 11,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
val expected = listOf(aMove2, bMove)
// Act
- val pointerInputHandler = pointerInteropFilter.pointerInputFilter::onPointerInput
- pointerInputHandler.invokeOverAllPasses(aDown)
- pointerInputHandler.invokeOverAllPasses(aMove1, bDownConsumed)
- val actual = pointerInputHandler.invokeOverAllPasses(aMove2, bMove)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDownConsumed, motionEvent = motionEvent2)
+ )
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
// Assert
assertThat(actual).isEqualTo(expected)
@@ -1286,92 +2654,247 @@
// Verifies resetting of consumption.
@Test
- fun onPointerInput_down1ConsumedThenUp1ThenDown2_finalDownConsumed() {
+ fun onPointerEvent_down1ConsumedThenUp1ThenDown2_finalDownConsumed() {
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aUp = aDownConsumed.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(
+ PointerProperties(0)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f)
+ )
+ )
val bDown = down(11, 12.milliseconds, 13f, 14f)
+ val motionEvent3 =
+ MotionEvent(
+ 12,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(13f, 14f))
+ )
val expected = bDown.consumeAllChanges()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent2)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bDown, motionEvent = motionEvent3)
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_down1ConsumedThenDown2ThenUp1ThenUp2ThenDown3_finalDownConsumed() {
+ fun onPointerEvent_down1ConsumedThenDown2ThenUp1ThenUp2ThenDown3_finalDownConsumed() {
// Arrange
val aDownConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDownConsumed.moveTo(22.milliseconds, 3f, 4f)
val bDown = down(21, 22.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 22,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aUp = aMove1.up(31.milliseconds)
val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val bUp = bMove1.up(41.milliseconds)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(1)),
+ arrayOf(PointerCoords(23f, 24f))
+ )
val cDown = down(51, 52.milliseconds, 53f, 54f)
+ val motionEvent5 =
+ MotionEvent(
+ 52,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(53f, 54f))
+ )
val expected = cDown.consumeAllChanges()
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDownConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDownConsumed, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(bUp)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bUp, motionEvent = motionEvent4)
+ )
val actual =
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(cDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(cDown, motionEvent = motionEvent5)
+ )
// Assert
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
// Verification of consumption when the view rets false and then is set to return true.
@Test
- fun onPointerInput_viewRetsFalseDownThenViewRetsTrueMove_noConsumptionOfMove() {
+ fun onPointerEvent_viewRetsFalseDownThenViewRetsTrueMove_noConsumptionOfMove() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent2 =
+ MotionEvent(
+ 2,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 7f))
+ )
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(aMove)
+ assertThat(actual.first()).isEqualTo(aMove)
}
@Test
- fun onPointerInput_viewRetsFalseDownThenViewRetsTrueUp_noConsumptionOfUp() {
+ fun onPointerEvent_viewRetsFalseDownThenViewRetsTrueUp_noConsumptionOfUp() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aUp = aDown.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aUp)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, motionEvent = motionEvent2)
+ )
- assertThat(actual).isEqualTo(aUp)
+ assertThat(actual.first()).isEqualTo(aUp)
}
@Test
- fun onPointerInput_viewRestsFalseDown1ThenViewRetsTrueDown2_noConsumptionOfDown2() {
+ fun onPointerEvent_viewRestsFalseDown1ThenViewRetsTrueDown2_noConsumptionOfDown2() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(5.milliseconds, 6f, 7f)
+ val aMove1 = aDown.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
mockViewGroup.returnValue = false
@@ -1379,10 +2902,14 @@
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove1, bDown)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Assert
@@ -1390,17 +2917,44 @@
}
@Test
- fun onPointerInput_viewRestsFalseDown1ThenViewRetsTrueDown2TheMove_noConsumptionOfMove() {
+ fun onPointerEvent_viewRestsFalseDown1ThenViewRetsTrueDown2TheMove_noConsumptionOfMove() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(5.milliseconds, 6f, 7f)
+ val aMove1 = aDown.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
val aMove2 = aMove1.moveTo(21.milliseconds, 22f, 23f)
val bMove1 = bDown.moveBy(21.milliseconds, 24f, 25f)
+ val motionEvent3 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(22f, 23f), PointerCoords(24f, 25f))
+ )
mockViewGroup.returnValue = false
@@ -1408,11 +2962,17 @@
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bMove1)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove1, motionEvent = motionEvent3)
+ )
// Assert
@@ -1420,17 +2980,44 @@
}
@Test
- fun onPointerInput_viewRestsFalseDown1ThenViewRetsTrueDown2TheUp2_noConsumptionOfUp() {
+ fun onPointerEvent_viewRestsFalseDown1ThenViewRetsTrueDown2TheUp2_noConsumptionOfUp() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(5.milliseconds, 6f, 7f)
+ val aMove1 = aDown.moveTo(5.milliseconds, 3f, 4f)
val bDown = down(11, 5.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
- val aMove2 = aMove1.moveTo(21.milliseconds, 6f, 7f)
+ val aMove2 = aMove1.moveTo(21.milliseconds, 3f, 4f)
val bUp = bDown.up(21.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 21,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
mockViewGroup.returnValue = false
@@ -1438,11 +3025,17 @@
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(aMove2, bUp)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3)
+ )
// Assert
@@ -1450,111 +3043,286 @@
}
@Test
- fun onPointerInput_down1ViewRetsFalseThenViewRestsTrueDown2ThenUp1ThenDown3_down3NotConsumed() {
+ fun onPointerEvent_down1ViewRetsFalseThenViewRestsTrueDown2ThenUp1ThenDown3_down3NotConsumed() {
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
- val bDown = down(21, 22.milliseconds, 23f, 24f)
+ val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 2,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aUp = aMove1.up(31.milliseconds)
val bMove1 = bDown.moveTo(31.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val bMove2 = bMove1.moveTo(41.milliseconds, 23f, 24f)
val cDown = down(51, 41.milliseconds, 52f, 53f)
+ val motionEvent4 =
+ MotionEvent(
+ 41,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(1), PointerProperties(0)),
+ arrayOf(PointerCoords(23f, 24f), PointerCoords(52f, 53f))
+ )
mockViewGroup.returnValue = false
val expected = listOf(bMove2, cDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aUp, bMove1)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aUp, bMove1, motionEvent = motionEvent3)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(bMove2, cDown)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(bMove2, cDown, motionEvent = motionEvent4)
+ )
assertThat(actual).isEqualTo(expected)
}
@Test
- fun onPointerInput_downThenMoveViewRetsFalseThenViewRetsTrueMove_moveNotConsumed() {
+ fun onPointerEvent_downThenMoveViewRetsFalseThenViewRetsTrueMove_moveNotConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val move1 = down.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 47f))
+ )
val move2 = move1.moveTo(10.milliseconds, 11f, 12f)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(11f, 12f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move1)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move1, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(move2)
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move2, motionEvent = motionEvent3)
+ )
- assertThat(actual).isEqualTo(move2)
+ assertThat(actual.first()).isEqualTo(move2)
}
@Test
- fun onPointerInput_downThenMoveViewRetsFalseThenViewRetsTrueThenUp_UpNotConsumed() {
+ fun onPointerEvent_downThenMoveViewRetsFalseThenViewRetsTrueThenUp_UpNotConsumed() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val move1 = down.moveTo(5.milliseconds, 6f, 7f)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 47f))
+ )
val up = move1.up(10.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 10,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(6f, 47f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(move1)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(move1, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverAllPasses(up)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent3)
+ )
- assertThat(actual).isEqualTo(up)
+ assertThat(actual.first()).isEqualTo(up)
}
@Test
- fun onPointerInput_down1ThenDown2ViewRetsFalseThenViewRetsTrueMove_moveNotConsumed() {
+ fun onPointerEvent_down1ThenDown2ViewRetsFalseThenViewRetsTrueMove_moveNotConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 2,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aMove2 = aMove1.moveTo(31.milliseconds, 31f, 32f)
val bMove = bDown.moveTo(31.milliseconds, 33f, 34f)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_MOVE,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(31f, 32f), PointerCoords(33f, 34f))
+ )
val expected = listOf(aMove2, bMove)
// Act
- val pointerInputHandler = pointerInteropFilter.pointerInputFilter::onPointerInput
- pointerInputHandler.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- pointerInputHandler.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInputHandler.invokeOverAllPasses(aMove2, bMove)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bMove, motionEvent = motionEvent3)
+ )
// Assert
assertThat(actual).isEqualTo(expected)
}
@Test
- fun onPointerInput_down1ThenDown2ViewRetsFalseThenViewRetsTrueUp2_moveNotConsumed() {
+ fun onPointerEvent_down1ThenDown2ViewRetsFalseThenViewRetsTrueUp2_moveNotConsumed() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(11.milliseconds, 3f, 4f)
val bDown = down(21, 11.milliseconds, 23f, 24f)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_POINTER_DOWN,
+ 2,
+ 2,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val aMove2 = aMove1.moveTo(31.milliseconds, 31f, 32f)
val bUp = bDown.up(31.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 31,
+ ACTION_POINTER_UP,
+ 2,
+ 2,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(23f, 24f))
+ )
val expected = listOf(aMove2, bUp)
// Act
- val pointerInputHandler = pointerInteropFilter.pointerInputFilter::onPointerInput
- pointerInputHandler.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
mockViewGroup.returnValue = false
- pointerInputHandler.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
mockViewGroup.returnValue = true
- val actual = pointerInputHandler.invokeOverAllPasses(aMove2, bUp)
+ val actual =
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3)
+ )
// Assert
assertThat(actual).isEqualTo(expected)
@@ -1563,115 +3331,20 @@
// Verification of correct passes being used
@Test
- fun onPointerInput_1PointerDown_dispatchedDuringInitialTunnel() {
+ fun onPointerEvent_1PointerDown_dispatchedDuringInitialTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(down, PointerEventPass.InitialDown)
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- }
-
- @Test
- fun onPointerInput_1PointerUp_dispatchedDuringInitialTunnel() {
- val down = down(1, 2.milliseconds, 3f, 4f)
- val up = down.up(5.milliseconds)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(up, PointerEventPass.InitialDown)
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- }
-
- @Test
- fun onPointerInput_2PointersDown_dispatchedDuringInitialTunnel() {
-
- // Arrange
-
- val aDown = down(1, 2.milliseconds, 3f, 4f)
-
- val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
- val bDown = down(8, 7.milliseconds, 10f, 11f)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
-
- // Act
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- aMove, bDown,
- pointerEventPass = PointerEventPass.InitialDown
- )
-
- // Assert
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- }
-
- @Test
- fun onPointerInput_2Pointers1Up_dispatchedDuringInitialTunnel() {
-
- // Arrange
-
- val aDown = down(1, 2.milliseconds, 3f, 4f)
-
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
- val bDown = down(8, 7.milliseconds, 10f, 11f)
-
- val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
- val bUp = bDown.up(13.milliseconds)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
-
- // Act
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- aMove2, bUp,
- pointerEventPass = PointerEventPass.InitialDown
- )
-
- // Assert
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
- }
-
- @Test
- fun onPointerInput_pointerMove_dispatchedDuringPostTunnel() {
- val down = down(1, 2.milliseconds, 3f, 4f)
- val move = down.moveTo(7.milliseconds, 8f, 9f)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
- PointerEventPass.InitialDown,
- PointerEventPass.PreUp,
- PointerEventPass.PreDown,
- PointerEventPass.PostUp
- )
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
- PointerEventPass.PostDown
- )
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- }
-
- @Test
- fun onPointerInput_downDisallowInterceptRequestedMove_moveDispatchedDuringInitialTunnel() {
- val down = down(1, 2.milliseconds, 3f, 4f)
- val move = down.moveTo(7.milliseconds, 8f, 9f)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- mockViewGroup.dispatchedMotionEvents.clear()
-
- mockViewGroup.requestDisallowInterceptTouchEvent(true)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(down, motionEvent = motionEvent1),
PointerEventPass.InitialDown
)
@@ -1679,90 +3352,77 @@
}
@Test
- fun onPointerInput_disallowInterceptRequestedUpDownMove_moveDispatchedDuringPostTunnel() {
- val downA = down(1, 2.milliseconds, 3f, 4f)
- val upA = downA.up(11.milliseconds)
- val downB = down(21, 22.milliseconds, 23f, 24f)
- val moveB = downB.moveTo(31.milliseconds, 32f, 33f)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(downA)
- mockViewGroup.requestDisallowInterceptTouchEvent(true)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(upA)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(downB)
- mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- moveB,
- PointerEventPass.InitialDown,
- PointerEventPass.PreUp,
- PointerEventPass.PreDown,
- PointerEventPass.PostUp
- )
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- moveB,
- PointerEventPass.PostDown
- )
-
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- }
-
- @Test
- fun onPointerInput_disallowInterceptTrueThenFalseThenMove_moveDispatchedDuringPostTunnel() {
+ fun onPointerEvent_1PointerUp_dispatchedDuringInitialTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
- val move = down.moveTo(7.milliseconds, 8f, 9f)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- mockViewGroup.requestDisallowInterceptTouchEvent(true)
- mockViewGroup.requestDisallowInterceptTouchEvent(false)
- mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
- PointerEventPass.InitialDown,
- PointerEventPass.PreUp,
- PointerEventPass.PreDown,
- PointerEventPass.PostUp
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val up = down.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
)
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
- PointerEventPass.PostDown
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(up, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
)
- assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- }
-
- @Test
- fun onPointerInput_1PointerUpConsumed_dispatchDuringInitialTunnel() {
- val down = down(1, 2.milliseconds, 3f, 4f)
- val upConsumed = down.up(5.milliseconds).consumeDownChange()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
-
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(upConsumed, PointerEventPass.InitialDown)
-
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
}
@Test
- fun onPointerInput_2PointersDown2ndDownConsumed_dispatchDuringInitialTunnel() {
+ fun onPointerEvent_2PointersDown_dispatchedDuringInitialTunnel() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
- val bDownConsumed = down(8, 7.milliseconds, 10f, 11f).consumeDownChange()
+ val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(aMove, bDownConsumed, pointerEventPass = PointerEventPass.InitialDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove, bDown, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
+ )
// Assert
@@ -1770,25 +3430,58 @@
}
@Test
- fun onPointerInput_2Pointers1UpConsumed_dispatchDuringInitialTunnel() {
+ fun onPointerEvent_2Pointers1Up_dispatchedDuringInitialTunnel() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
- val bUpConsumed = bDown.up(13.milliseconds).consumeDownChange()
+ val bUp = bDown.up(13.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 13,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(aMove2, bUpConsumed, pointerEventPass = PointerEventPass.InitialDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3),
+ PointerEventPass.InitialDown
+ )
// Assert
@@ -1796,13 +3489,378 @@
}
@Test
- fun onPointerInput_1PointerMoveConsumed_dispatchDuringPostTunnel() {
+ fun onPointerEvent_pointerMove_dispatchedDuringPostTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
- val moveConsumed = down.moveTo(7.milliseconds, 8f, 9f).consume(1f, 0f)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ mockViewGroup.dispatchedMotionEvents.clear()
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown,
+ PointerEventPass.PreUp,
+ PointerEventPass.PreDown,
+ PointerEventPass.PostUp
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- moveConsumed,
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
+ PointerEventPass.PostDown
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
+ }
+
+ @Test
+ fun onPointerEvent_downDisallowInterceptRequestedMove_moveDispatchedDuringInitialTunnel() {
+ val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ mockViewGroup.dispatchedMotionEvents.clear()
+
+ mockViewGroup.requestDisallowInterceptTouchEvent(true)
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
+ }
+
+ @Test
+ fun onPointerEvent_disallowInterceptRequestedUpDownMove_moveDispatchedDuringPostTunnel() {
+ val downA = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val upA = downA.up(11.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 11,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val downB = down(21, 22.milliseconds, 23f, 24f)
+ val motionEvent3 =
+ MotionEvent(
+ 21,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(23f, 24f))
+ )
+ val moveB = downB.moveTo(31.milliseconds, 32f, 33f)
+ val motionEvent4 =
+ MotionEvent(
+ 31,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(32f, 33f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(downA, motionEvent = motionEvent1)
+ )
+ mockViewGroup.requestDisallowInterceptTouchEvent(true)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(upA, motionEvent = motionEvent2)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(downB, motionEvent = motionEvent3)
+ )
+ mockViewGroup.dispatchedMotionEvents.clear()
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(moveB, motionEvent = motionEvent4),
+ PointerEventPass.InitialDown,
+ PointerEventPass.PreUp,
+ PointerEventPass.PreDown,
+ PointerEventPass.PostUp
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(moveB, motionEvent = motionEvent4),
+ PointerEventPass.PostDown
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
+ }
+
+ @Test
+ fun onPointerEvent_disallowInterceptTrueThenFalseThenMove_moveDispatchedDuringPostTunnel() {
+ val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ mockViewGroup.requestDisallowInterceptTouchEvent(true)
+ mockViewGroup.requestDisallowInterceptTouchEvent(false)
+ mockViewGroup.dispatchedMotionEvents.clear()
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown,
+ PointerEventPass.PreUp,
+ PointerEventPass.PreDown,
+ PointerEventPass.PostUp
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(0)
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
+ PointerEventPass.PostDown
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
+ }
+
+ @Test
+ fun onPointerEvent_1PointerUpConsumed_dispatchDuringInitialTunnel() {
+ val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val upConsumed = down.up(5.milliseconds).consumeDownChange()
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(upConsumed, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
+ )
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
+ }
+
+ @Test
+ fun onPointerEvent_2PointersDown2ndDownConsumed_dispatchDuringInitialTunnel() {
+
+ // Arrange
+
+ val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
+ val bDownConsumed = down(8, 7.milliseconds, 10f, 11f).consumeDownChange()
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_CANCEL,
+ 2,
+ 0,
+ arrayOf(
+ PointerProperties(0),
+ PointerProperties(1)
+ ),
+ arrayOf(
+ PointerCoords(3f, 4f),
+ PointerCoords(10f, 11f)
+ )
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+
+ // Act
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove, bDownConsumed, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
+ )
+
+ // Assert
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
+ }
+
+ @Test
+ fun onPointerEvent_2Pointers1UpConsumed_dispatchDuringInitialTunnel() {
+
+ // Arrange
+
+ val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
+ val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
+
+ val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
+ val bUpConsumed = bDown.up(13.milliseconds).consumeDownChange()
+ val motionEvent3 =
+ MotionEvent(
+ 13,
+ ACTION_CANCEL,
+ 2,
+ 0,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
+
+ // Act
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove2, bUpConsumed, motionEvent = motionEvent3),
+ PointerEventPass.InitialDown
+ )
+
+ // Assert
+
+ assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
+ }
+
+ @Test
+ fun onPointerEvent_1PointerMoveConsumed_dispatchDuringPostTunnel() {
+ val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val moveConsumed = down.moveTo(7.milliseconds, 8f, 9f).consume(1f, 0f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_CANCEL,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(moveConsumed, motionEvent = motionEvent2),
PointerEventPass.InitialDown,
PointerEventPass.PreUp,
PointerEventPass.PreDown,
@@ -1811,8 +3869,8 @@
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- moveConsumed,
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(moveConsumed, motionEvent = motionEvent2),
PointerEventPass.PostDown
)
@@ -1820,90 +3878,174 @@
}
@Test
- fun onPointerInput_2PointersMoveConsumed_dispatchDuringPostTunnel() {
+ fun onPointerEvent_2PointersMoveConsumed_dispatchDuringPostTunnel() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(11, 7.milliseconds, 13f, 14f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(13f, 14f))
+ )
val aMove2 = aMove1.moveTo(15.milliseconds, 8f, 9f)
val bMoveConsumed = bDown.moveTo(15.milliseconds, 18f, 19f).consume(1f, 0f)
+ val motionEvent3 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(8f, 9f), PointerCoords(18f, 19f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act 1
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(
- listOf(aMove2, bMoveConsumed),
- listOf(
- PointerEventPass.InitialDown,
- PointerEventPass.PreUp,
- PointerEventPass.PreDown,
- PointerEventPass.PostUp
- )
- )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove2, bMoveConsumed, motionEvent = motionEvent3),
+ PointerEventPass.InitialDown,
+ PointerEventPass.PreUp,
+ PointerEventPass.PreDown,
+ PointerEventPass.PostUp
+ )
// Assert 1
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(2)
- pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(
- aMove2, bMoveConsumed,
- pointerEventPass = PointerEventPass.PostDown
- )
+ // Act 2
+
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove2, bMoveConsumed, motionEvent = motionEvent3),
+ PointerEventPass.PostDown
+ )
+
+ // Assert 2
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(3)
}
@Test
- fun onPointerInput_1PointerDown_consumedDuringInitialTunnel() {
+ fun onPointerEvent_1PointerDown_consumedDuringInitialTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val expected = down.consumeAllChanges()
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(down, PointerEventPass.InitialDown)
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(down, motionEvent = motionEvent1),
+ PointerEventPass.InitialDown
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_1PointerUp_consumedDuringInitialTunnel() {
+ fun onPointerEvent_1PointerUp_consumedDuringInitialTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val up = down.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val expected = up.consumeAllChanges()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput
- .invokeOverPasses(up, PointerEventPass.InitialDown)
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(up, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
+ )
- assertThat(actual).isEqualTo(expected)
+ assertThat(actual.first()).isEqualTo(expected)
}
@Test
- fun onPointerInput_2PointersDown_consumedDuringInitialTunnel() {
+ fun onPointerEvent_2PointersDown_consumedDuringInitialTunnel() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val aMove = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val expected = listOf(aMove, bDown).map { it.consumeAllChanges() }
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
// Act
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- aMove, bDown,
- pointerEventPass = PointerEventPass.InitialDown
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove, bDown, motionEvent = motionEvent2),
+ PointerEventPass.InitialDown
)
// Assert
@@ -1912,28 +4054,59 @@
}
@Test
- fun onPointerInput_2Pointers1Up_consumedDuringInitialTunnel() {
+ fun onPointerEvent_2Pointers1Up_consumedDuringInitialTunnel() {
// Arrange
val aDown = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- val aMove1 = aDown.moveTo(12.milliseconds, 3f, 4f)
+ val aMove1 = aDown.moveTo(7.milliseconds, 3f, 4f)
val bDown = down(8, 7.milliseconds, 10f, 11f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_POINTER_DOWN,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val aMove2 = aMove1.moveTo(13.milliseconds, 3f, 4f)
val bUp = bDown.up(13.milliseconds)
+ val motionEvent3 =
+ MotionEvent(
+ 13,
+ ACTION_POINTER_UP,
+ 2,
+ 1,
+ arrayOf(PointerProperties(0), PointerProperties(1)),
+ arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
+ )
val expected = listOf(aMove2, bUp).map { it.consumeAllChanges() }
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aDown)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(aMove1, bDown)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aDown, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(aMove1, bDown, motionEvent = motionEvent2)
+ )
// Act
- val actual = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- aMove2, bUp,
- pointerEventPass = PointerEventPass.InitialDown
+ val actual = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(aMove2, bUp, motionEvent = motionEvent3),
+ PointerEventPass.InitialDown
)
// Assert
@@ -1942,36 +4115,67 @@
}
@Test
- fun onPointerInput_pointerMove_consumedDuringPostTunnel() {
+ fun onPointerEvent_pointerMove_consumedDuringPostTunnel() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val move = down.moveTo(7.milliseconds, 8f, 9f)
+ val motionEvent2 =
+ MotionEvent(
+ 7,
+ ACTION_MOVE,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(8f, 9f))
+ )
val expected2 = move.consumeAllChanges()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
- val actual1 = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
+ val actual1 = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
PointerEventPass.InitialDown,
PointerEventPass.PreUp,
PointerEventPass.PreDown,
PointerEventPass.PostUp
)
- assertThat(actual1).isEqualTo(move)
+ assertThat(actual1.first()).isEqualTo(move)
- val actual2 = pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverPasses(
- move,
+ val actual2 = pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverPasses(
+ pointerEventOf(move, motionEvent = motionEvent2),
PointerEventPass.PostDown
)
- assertThat(actual2).isEqualTo(expected2)
+ assertThat(actual2.first()).isEqualTo(expected2)
}
@Test
fun onCancel_cancelEventIsCorrect() {
val down = down(1, 2.milliseconds, 3f, 4f)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2002,8 +4206,20 @@
@Test
fun onCancel_downConsumedCancel_cancelNotDispatched() {
val downConsumed = down(1, 2.milliseconds, 3f, 4f).consumeDownChange()
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(downConsumed)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(downConsumed, motionEvent = motionEvent1)
+ )
+
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2013,9 +4229,20 @@
@Test
fun onCancel_downViewRetsFalseThenCancel_cancelNotDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
mockViewGroup.returnValue = false
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2025,10 +4252,32 @@
@Test
fun onCancel_downThenUpOnCancel_cancelNotDispatched() {
val down = down(1, 2.milliseconds, 3f, 4f)
- val up = down.up(11.milliseconds)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
+ val up = down.up(5.milliseconds)
+ val motionEvent2 =
+ MotionEvent(
+ 5,
+ ACTION_UP,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(up)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(up, motionEvent = motionEvent2)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2038,8 +4287,19 @@
@Test
fun onCancel_downThenOnCancel_cancelDispatchedOnce() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2049,8 +4309,19 @@
@Test
fun onCancel_downThenOnCancelThenOnCancel_cancelDispatchedOnce() {
val down = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
pointerInteropFilter.pointerInputFilter.onCancel()
@@ -2061,15 +4332,37 @@
@Test
fun onCancel_downThenOnCancelThenDownThenOnCancel_cancelDispatchedTwice() {
val down1 = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent1 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
val down2 = down(1, 2.milliseconds, 3f, 4f)
+ val motionEvent2 =
+ MotionEvent(
+ 2,
+ ACTION_DOWN,
+ 1,
+ 0,
+ arrayOf(PointerProperties(0)),
+ arrayOf(PointerCoords(3f, 4f))
+ )
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down1)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down1, motionEvent = motionEvent1)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
mockViewGroup.dispatchedMotionEvents.clear()
- pointerInteropFilter.pointerInputFilter::onPointerInput.invokeOverAllPasses(down2)
+ pointerInteropFilter.pointerInputFilter::onPointerEvent.invokeOverAllPasses(
+ pointerEventOf(down2, motionEvent = motionEvent2)
+ )
mockViewGroup.dispatchedMotionEvents.clear()
pointerInteropFilter.pointerInputFilter.onCancel()
assertThat(mockViewGroup.dispatchedMotionEvents).hasSize(1)
@@ -2081,7 +4374,7 @@
var returnValue = true
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
- dispatchedMotionEvents.add(MotionEvent.obtain(ev))
+ dispatchedMotionEvents.add(ev!!)
return returnValue
}
}
@@ -2110,8 +4403,7 @@
eventTime.toLong(),
action + (actionIndex shl MotionEvent.ACTION_POINTER_INDEX_SHIFT),
numPointers,
- // TODO(shepshapard): This is bad and temporary
- pointerProperties.map { PointerProperties(it.id % 32) }.toTypedArray(),
+ pointerProperties,
pointerCoords,
0,
0,
@@ -2123,27 +4415,42 @@
0
)
-private fun assertEquals(actual: MotionEvent, expected: MotionEvent) {
- assertThat(actual.downTime).isEqualTo(expected.downTime)
- assertThat(actual.eventTime).isEqualTo(expected.eventTime)
- assertThat(actual.actionMasked).isEqualTo(expected.actionMasked)
- assertThat(actual.actionIndex).isEqualTo(expected.actionIndex)
- assertThat(actual.pointerCount).isEqualTo(expected.pointerCount)
+private typealias PointerEventHandler =
+ (PointerEvent, PointerEventPass, IntSize) -> List<PointerInputChange>
- val actualPointerProperties = MotionEvent.PointerProperties()
- val expectedPointerProperties = MotionEvent.PointerProperties()
- repeat(expected.pointerCount) { index ->
- actual.getPointerProperties(index, actualPointerProperties)
- expected.getPointerProperties(index, expectedPointerProperties)
- assertThat(actualPointerProperties).isEqualTo(expectedPointerProperties)
- }
+private fun PointerEventHandler.invokeOverAllPasses(
+ pointerEvent: PointerEvent,
+ size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
+) = invokeOverPasses(
+ pointerEvent,
+ listOf(
+ PointerEventPass.InitialDown,
+ PointerEventPass.PreUp,
+ PointerEventPass.PreDown,
+ PointerEventPass.PostUp,
+ PointerEventPass.PostDown
+ ),
+ size = size
+)
- val actualPointerCoords = MotionEvent.PointerCoords()
- val expectedPointerCoords = MotionEvent.PointerCoords()
- repeat(expected.pointerCount) { index ->
- actual.getPointerCoords(index, actualPointerCoords)
- expected.getPointerCoords(index, expectedPointerCoords)
- assertThat(actualPointerCoords.x).isEqualTo(expectedPointerCoords.x)
- assertThat(actualPointerCoords.y).isEqualTo(expectedPointerCoords.y)
+private fun PointerEventHandler.invokeOverPasses(
+ pointerEvent: PointerEvent,
+ vararg pointerEventPasses: PointerEventPass,
+ size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
+) = invokeOverPasses(pointerEvent, pointerEventPasses.toList(), size)
+
+private fun PointerEventHandler.invokeOverPasses(
+ pointerEvent: PointerEvent,
+ pointerEventPasses: List<PointerEventPass>,
+ size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
+): List<PointerInputChange> {
+ require(pointerEventPasses.isNotEmpty())
+ var localChanges: List<PointerInputChange> = pointerEvent.changes
+ pointerEventPasses.forEach {
+ localChanges = this.invoke(PointerEvent(localChanges, pointerEvent.motionEvent), it, size)
}
-}
\ No newline at end of file
+ return localChanges
+}
+
+private fun pointerEventOf(vararg changes: PointerInputChange, motionEvent: MotionEvent? = null) =
+ PointerEvent(changes.toList(), motionEvent = motionEvent)
\ No newline at end of file
diff --git a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropUtilsTest.kt b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropUtilsTest.kt
index a22fb7a..dd9d72a 100644
--- a/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropUtilsTest.kt
+++ b/ui/ui-core/src/androidAndroidTest/kotlin/androidx/ui/node/PointerInteropUtilsTest.kt
@@ -19,13 +19,13 @@
import android.view.MotionEvent
import android.view.View
import androidx.test.filters.SmallTest
-import androidx.ui.core.PointerInputChange
+import androidx.ui.core.PointerEvent
+import androidx.ui.geometry.Offset
import androidx.ui.testutils.down
import androidx.ui.testutils.moveTo
import androidx.ui.testutils.up
-import androidx.ui.unit.IntOffset
import androidx.ui.unit.milliseconds
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -34,15 +34,14 @@
@RunWith(JUnit4::class)
class PointerInteropUtilsTest {
- @Test(expected = IllegalStateException::class)
- fun toMotionEventScope_emptyList_throws() {
- val list = listOf<PointerInputChange>()
- list.toMotionEventScope(IntOffset.Origin) {}
+ @Test(expected = IllegalArgumentException::class)
+ fun toMotionEventScope_noPlatformEvent_throws() {
+ val pointerEvent = PointerEvent(listOf(), motionEvent = null)
+ pointerEvent.toMotionEventScope(Offset.Zero) {}
}
@Test
fun toMotionEventScope_1stPointerDownEvent_motionEventIsCorrect() {
- val list = listOf(down(1, 2.milliseconds, 3f, 4f))
val expected =
MotionEvent(
2,
@@ -52,18 +51,18 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(3f, 4f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(down(1, 2.milliseconds, 3f, 4f)), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_1stPointerUpEvent_motionEventIsCorrect() {
- val list = listOf(down(1, 2.milliseconds, 3f, 4f).up(5.milliseconds))
val expected =
MotionEvent(
5,
@@ -73,21 +72,23 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(3f, 4f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(
+ listOf(down(1, 2.milliseconds, 3f, 4f).up(5.milliseconds)),
+ expected
+ )
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_2ndPointerDownEventAs1stPointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 7.milliseconds, 10f, 11f)
-
- val list = listOf(pointer1, pointer2)
val expected =
MotionEvent(
7,
@@ -97,21 +98,20 @@
arrayOf(PointerProperties(1), PointerProperties(8)),
arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1, pointer2), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_2ndPointerDownEventAs2ndPointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 7.milliseconds, 10f, 11f)
-
- val list = listOf(pointer2, pointer1)
val expected =
MotionEvent(
7,
@@ -121,21 +121,20 @@
arrayOf(PointerProperties(8), PointerProperties(1)),
arrayOf(PointerCoords(10f, 11f), PointerCoords(3f, 4f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer2, pointer1), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_2ndPointerUpEventAs1stPointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 2.milliseconds, 10f, 11f).up(7.milliseconds)
-
- val list = listOf(pointer1, pointer2)
val expected =
MotionEvent(
7,
@@ -145,21 +144,20 @@
arrayOf(PointerProperties(1), PointerProperties(8)),
arrayOf(PointerCoords(3f, 4f), PointerCoords(10f, 11f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1, pointer2), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_2ndPointerUpEventAs2ndPointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 2.milliseconds, 10f, 11f).up(7.milliseconds)
-
- val list = listOf(pointer2, pointer1)
val expected =
MotionEvent(
7,
@@ -169,20 +167,19 @@
arrayOf(PointerProperties(8), PointerProperties(1)),
arrayOf(PointerCoords(10f, 11f), PointerCoords(3f, 4f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer2, pointer1), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_moveEvent1Pointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 8f, 9f)
-
- val list = listOf(pointer1)
val expected =
MotionEvent(
7,
@@ -192,21 +189,20 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(8f, 9f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_moveEvent2Pointers_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 8f, 9f)
val pointer2 = down(11, 12.milliseconds, 13f, 14f).moveTo(17.milliseconds, 18f, 19f)
-
- val list = listOf(pointer1, pointer2)
val expected =
MotionEvent(
7,
@@ -216,20 +212,19 @@
arrayOf(PointerProperties(1), PointerProperties(11)),
arrayOf(PointerCoords(8f, 9f), PointerCoords(18f, 19f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1, pointer2), expected)
- list.toMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_globalOffsetsSet1Pointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f)
-
- val list = listOf(pointer1)
val expected =
MotionEvent(
2,
@@ -239,21 +234,20 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(13f, 104f))
).apply { offsetLocation(-10f, -100f) }
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1), expected)
- list.toMotionEventScope(IntOffset(10, 100)) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset(10f, 100f)) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toMotionEventScope_globalOffsetsSet2Pointers_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 7.milliseconds, 10f, 11f)
-
- val list = listOf(pointer2, pointer1)
val expected =
MotionEvent(
7,
@@ -263,26 +257,25 @@
arrayOf(PointerProperties(8), PointerProperties(1)),
arrayOf(PointerCoords(110f, 1011f), PointerCoords(103f, 1004f))
).apply { offsetLocation(-100f, -1000f) }
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer2, pointer1), expected)
- list.toMotionEventScope(IntOffset(100, 1000)) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toMotionEventScope(Offset(100f, 1000f)) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
- @Test(expected = IllegalStateException::class)
- fun toCancelMotionEventScope_emptyList_throws() {
- val list = listOf<PointerInputChange>()
- list.toCancelMotionEventScope(IntOffset.Origin) {}
+ @Test(expected = IllegalArgumentException::class)
+ fun toCancelMotionEventScope_noPlatformEvent_throws() {
+ val pointerEvent = PointerEvent(listOf(), motionEvent = null)
+ pointerEvent.toCancelMotionEventScope(Offset.Zero) {}
}
@Test
fun toCancelMotionEventScope_1Pointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 8f, 9f)
-
- val list = listOf(pointer1)
val expected =
MotionEvent(
7,
@@ -292,21 +285,20 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(8f, 9f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1), expected)
- list.toCancelMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toCancelMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toCancelMotionEventScope_2Pointers_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 8f, 9f)
val pointer2 = down(11, 12.milliseconds, 13f, 14f).moveTo(17.milliseconds, 18f, 19f)
-
- val list = listOf(pointer1, pointer2)
val expected =
MotionEvent(
7,
@@ -316,21 +308,20 @@
arrayOf(PointerProperties(1), PointerProperties(11)),
arrayOf(PointerCoords(8f, 9f), PointerCoords(18f, 19f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1, pointer2), expected)
- list.toCancelMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toCancelMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toCancelMotionEventScope_2PointersAltOrder_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 8f, 9f)
val pointer2 = down(11, 12.milliseconds, 13f, 14f).moveTo(7.milliseconds, 18f, 19f)
-
- val list = listOf(pointer2, pointer1)
val expected =
MotionEvent(
7,
@@ -340,20 +331,19 @@
arrayOf(PointerProperties(11), PointerProperties(1)),
arrayOf(PointerCoords(18f, 19f), PointerCoords(8f, 9f))
)
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer2, pointer1), expected)
- list.toCancelMotionEventScope(IntOffset.Origin) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toCancelMotionEventScope(Offset.Zero) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toCancelMotionEventScope_globalOffsetsSet1Pointer_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f)
-
- val list = listOf(pointer1)
val expected =
MotionEvent(
2,
@@ -363,21 +353,20 @@
arrayOf(PointerProperties(1)),
arrayOf(PointerCoords(13f, 104f))
).apply { offsetLocation(-10f, -100f) }
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer1), expected)
- list.toCancelMotionEventScope(IntOffset(10, 100)) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toCancelMotionEventScope(Offset(10f, 100f)) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
fun toCancelMotionEventScope_globalOffsetsSet2Pointers_motionEventIsCorrect() {
val pointer1 = down(1, 2.milliseconds, 3f, 4f).moveTo(7.milliseconds, 3f, 4f)
val pointer2 = down(8, 7.milliseconds, 10f, 11f)
-
- val list = listOf(pointer2, pointer1)
val expected =
MotionEvent(
7,
@@ -387,13 +376,14 @@
arrayOf(PointerProperties(8), PointerProperties(1)),
arrayOf(PointerCoords(110f, 1011f), PointerCoords(103f, 1004f))
).apply { offsetLocation(-100f, -1000f) }
- lateinit var actual: MotionEvent
+ val pointerEvent = PointerEvent(listOf(pointer2, pointer1), expected)
- list.toCancelMotionEventScope(IntOffset(100, 1000)) {
+ lateinit var actual: MotionEvent
+ pointerEvent.toCancelMotionEventScope(Offset(100f, 1000f)) {
actual = it
}
- assertEquals(actual, expected)
+ assertThat(actual).isSameInstanceAs(expected)
}
@Test
@@ -456,19 +446,16 @@
)
private fun assertEquals(actual: MotionEvent, expected: MotionEvent) {
- Truth.assertThat(actual.downTime).isEqualTo(expected.downTime)
- Truth.assertThat(actual.eventTime).isEqualTo(expected.eventTime)
- Truth.assertThat(actual.actionMasked).isEqualTo(expected.actionMasked)
- Truth.assertThat(actual.actionIndex).isEqualTo(expected.actionIndex)
- Truth.assertThat(actual.pointerCount).isEqualTo(expected.pointerCount)
+ assertThat(actual.downTime).isEqualTo(expected.downTime)
+ assertThat(actual.eventTime).isEqualTo(expected.eventTime)
+ assertThat(actual.actionMasked).isEqualTo(expected.actionMasked)
+ assertThat(actual.actionIndex).isEqualTo(expected.actionIndex)
+ assertThat(actual.pointerCount).isEqualTo(expected.pointerCount)
- val actualPointerProperties = MotionEvent.PointerProperties()
- val expectedPointerProperties = MotionEvent.PointerProperties()
- repeat(expected.pointerCount) { index ->
- actual.getPointerProperties(index, actualPointerProperties)
- expected.getPointerProperties(index, expectedPointerProperties)
- Truth.assertThat(actualPointerProperties).isEqualTo(expectedPointerProperties)
- }
+ assertEqualToolTypes(actual, expected)
+
+ // Equal pointer properties
+ assertEqualPointerProperties(actual, expected)
// Equal pointer coords relative to local region.
assertEqualPointerCoords(actual, expected)
@@ -480,6 +467,22 @@
)
}
+private fun assertEqualToolTypes(actual: MotionEvent, expected: MotionEvent) {
+ repeat(expected.pointerCount) { index ->
+ assertThat(actual.getToolType(index)).isEqualTo(expected.getToolType(index))
+ }
+}
+
+private fun assertEqualPointerProperties(actual: MotionEvent, expected: MotionEvent) {
+ val actualPointerProperties = MotionEvent.PointerProperties()
+ val expectedPointerProperties = MotionEvent.PointerProperties()
+ repeat(expected.pointerCount) { index ->
+ actual.getPointerProperties(index, actualPointerProperties)
+ expected.getPointerProperties(index, expectedPointerProperties)
+ assertThat(actualPointerProperties).isEqualTo(expectedPointerProperties)
+ }
+}
+
/**
* Asserts that 2 [MotionEvent]s' [PointerCoords] are the same.
*/
@@ -489,8 +492,8 @@
repeat(expected.pointerCount) { index ->
actual.getPointerCoords(index, actualPointerCoords)
expected.getPointerCoords(index, expectedPointerCoords)
- Truth.assertThat(actualPointerCoords.x).isEqualTo(expectedPointerCoords.x)
- Truth.assertThat(actualPointerCoords.y).isEqualTo(expectedPointerCoords.y)
+ assertThat(actualPointerCoords.x).isEqualTo(expectedPointerCoords.x)
+ assertThat(actualPointerCoords.y).isEqualTo(expectedPointerCoords.y)
}
}
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/PointerInput.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/PointerInput.kt
new file mode 100644
index 0000000..86bc03b
--- /dev/null
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/PointerInput.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 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 androidx.ui.core
+
+import android.view.MotionEvent
+import androidx.ui.core.pointerinput.PointerInputEvent
+
+internal actual class InternalPointerEvent constructor(
+ actual var changes: MutableMap<PointerId, PointerInputChange>,
+ val motionEvent: MotionEvent
+) {
+ actual constructor(
+ changes: MutableMap<PointerId, PointerInputChange>,
+ pointerInputEvent: PointerInputEvent
+ ) : this(changes, pointerInputEvent.motionEvent)
+}
+
+/**
+ * Describes a pointer input change event that has occurred at a particular point in time.
+ */
+actual class PointerEvent internal constructor(
+ /**
+ * The changes.
+ */
+ actual val changes: List<PointerInputChange>,
+ internal val motionEvent: MotionEvent?
+) {
+ internal actual constructor(
+ changes: List<PointerInputChange>,
+ internalPointerEvent: InternalPointerEvent?
+ ) : this(changes, internalPointerEvent?.motionEvent)
+
+ /**
+ * @param changes The changes.
+ */
+ actual constructor(changes: List<PointerInputChange>) : this(changes, motionEvent = null)
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/MotionEventAdapter.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/MotionEventAdapter.kt
index 84aa612..81a376c 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/MotionEventAdapter.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/MotionEventAdapter.kt
@@ -36,8 +36,12 @@
private var nextId = 0L
+ /**
+ * Whenever a new MotionEvent pointer is added, we create a new PointerId that is associated
+ * with it. This holds that association.
+ */
@VisibleForTesting
- internal val intIdToPointerIdMap: MutableMap<Int, PointerId> = mutableMapOf()
+ internal val motionEventToComposePointerIdMap: MutableMap<Int, PointerId> = mutableMapOf()
/**
* Converts a single [MotionEvent] from an Android event stream into a [PointerInputEvent], or
@@ -53,7 +57,7 @@
internal fun convertToPointerInputEvent(motionEvent: MotionEvent): PointerInputEvent? {
if (motionEvent.actionMasked == ACTION_CANCEL) {
- intIdToPointerIdMap.clear()
+ motionEventToComposePointerIdMap.clear()
return null
}
@@ -69,8 +73,11 @@
else -> null
}
+ // TODO(shepshapard): Avoid allocating for every event.
val pointers: MutableList<PointerInputEventData> = mutableListOf()
+ // This converts the MotionEvent into a list of PointerInputEventData, and updates
+ // internal record keeping.
@Suppress("NAME_SHADOWING")
motionEvent.asOffsetToScreen { motionEvent ->
for (i in 0 until motionEvent.pointerCount) {
@@ -80,20 +87,11 @@
return PointerInputEvent(
Uptime(motionEvent.eventTime * NanosecondsPerMillisecond),
- pointers
+ pointers,
+ motionEvent
)
}
- private inline fun MotionEvent.asOffsetToScreen(block: (MotionEvent) -> Unit) {
- // Mutate the motion event to be relative to the screen. This is required to create a
- // valid PointerInputEvent.
- val offsetX = rawX - x
- val offsetY = rawY - y
- offsetLocation(offsetX, offsetY)
- block(this)
- offsetLocation(-offsetX, -offsetY)
- }
-
/**
* Creates a new PointerInputEventData.
*/
@@ -104,18 +102,18 @@
upIndex: Int?
): PointerInputEventData {
- val pointerIdInt = motionEvent.getPointerId(index)
+ val motionEventPointerId = motionEvent.getPointerId(index)
val pointerId =
when (index) {
downIndex ->
PointerId(nextId++).also {
- intIdToPointerIdMap[pointerIdInt] = it
+ motionEventToComposePointerIdMap[motionEventPointerId] = it
}
upIndex ->
- intIdToPointerIdMap.remove(pointerIdInt)
+ motionEventToComposePointerIdMap.remove(motionEventPointerId)
else ->
- intIdToPointerIdMap[pointerIdInt]
+ motionEventToComposePointerIdMap[motionEventPointerId]
} ?: throw IllegalStateException(
"Compose assumes that all pointer ids in MotionEvents are first provided " +
"alongside ACTION_DOWN or ACTION_POINTER_DOWN. This appears not " +
@@ -132,24 +130,37 @@
)
)
}
+}
- /**
- * Creates a new PointerInputData.
- */
- private fun createPointerInputData(
- timestamp: Uptime,
- motionEvent: MotionEvent,
- index: Int,
- upIndex: Int?
- ): PointerInputData {
- val pointerCoords = MotionEvent.PointerCoords()
- motionEvent.getPointerCoords(index, pointerCoords)
- val offset = Offset(pointerCoords.x, pointerCoords.y)
+/**
+ * Creates a new PointerInputData.
+ */
+private fun createPointerInputData(
+ timestamp: Uptime,
+ motionEvent: MotionEvent,
+ index: Int,
+ upIndex: Int?
+): PointerInputData {
+ val pointerCoords = MotionEvent.PointerCoords()
+ motionEvent.getPointerCoords(index, pointerCoords)
+ val offset = Offset(pointerCoords.x, pointerCoords.y)
- return PointerInputData(
- timestamp,
- offset,
- index != upIndex
- )
- }
+ return PointerInputData(
+ timestamp,
+ offset,
+ index != upIndex
+ )
+}
+
+/**
+ * Mutates the MotionEvent to be relative to the screen.
+ *
+ * This is required to create a valid PointerInputEvent.
+ */
+private inline fun MotionEvent.asOffsetToScreen(block: (MotionEvent) -> Unit) {
+ val offsetX = rawX - x
+ val offsetY = rawY - y
+ offsetLocation(offsetX, offsetY)
+ block(this)
+ offsetLocation(-offsetX, -offsetY)
}
\ No newline at end of file
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt
new file mode 100644
index 0000000..c7c95cb
--- /dev/null
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 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 androidx.ui.core.pointerinput
+
+import android.view.MotionEvent
+import androidx.ui.unit.Uptime
+
+internal actual class PointerInputEvent(
+ actual val uptime: Uptime,
+ actual val pointers: List<PointerInputEventData>,
+ val motionEvent: MotionEvent
+)
\ No newline at end of file
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropFilter.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropFilter.kt
index 72fc578..616aa31 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropFilter.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropFilter.kt
@@ -18,6 +18,7 @@
import android.os.SystemClock
import androidx.ui.core.Modifier
+import androidx.ui.core.PointerEvent
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerInputChange
import androidx.ui.core.anyChangeConsumed
@@ -26,7 +27,7 @@
import androidx.ui.core.consumeAllChanges
import androidx.ui.core.pointerinput.PointerInputFilter
import androidx.ui.core.pointerinput.PointerInputModifier
-import androidx.ui.unit.IntOffset
+import androidx.ui.geometry.Offset
import androidx.ui.unit.IntSize
import androidx.ui.unit.milliseconds
import androidx.ui.util.fastAny
@@ -79,9 +80,6 @@
val view: AndroidViewHolder
) : PointerInputModifier {
- // Reusable to avoid extra allocations.
- private val reusableLocationInWindow by lazy { IntArray(2) }
-
/**
* The 3 possible states
*/
@@ -122,8 +120,18 @@
pass: PointerEventPass,
bounds: IntSize
): List<PointerInputChange> {
+ // No implementation as onPointerEvent is overridden.
+ // The super method will eventually be removed so this is just temporary.
+ throw NotImplementedError("This method is temporary and should never be called")
+ }
+
+ override fun onPointerEvent(
+ pointerEvent: PointerEvent,
+ pass: PointerEventPass,
+ bounds: IntSize
+ ): List<PointerInputChange> {
@Suppress("NAME_SHADOWING")
- var changes = changes
+ var changes = pointerEvent.changes
// If we were told to disallow intercept, or if the event was a down or up event,
// we dispatch to Android as early as possible. If the event is a move event and
@@ -136,10 +144,10 @@
if (state !== DispatchToViewState.NotDispatching) {
if (pass == PointerEventPass.InitialDown && dispatchDuringInitialTunnel) {
- changes = dispatchToView(changes)
+ changes = dispatchToView(pointerEvent)
}
if (pass == PointerEventPass.PostDown && !dispatchDuringInitialTunnel) {
- changes = dispatchToView(changes)
+ changes = dispatchToView(pointerEvent)
}
}
if (pass == PointerEventPass.PostDown) {
@@ -176,42 +184,33 @@
/**
* Dispatches to the Android View.
*
- * Also consumes aspects of [changes] and updates our [state] accordingly.
+ * Also consumes aspects of [pointerEvent] and updates our [state] accordingly.
*
- * Will dispatch ACTION_CANCEL if any aspect of [changes] has been consumed and
+ * Will dispatch ACTION_CANCEL if any aspect of [pointerEvent] has been consumed and
* update our [state] accordingly.
*
- * @param changes The changes to dispatch.
+ * @param pointerEvent The change to dispatch.
* @return The resulting changes (fully consumed or untouched).
*/
- private fun dispatchToView(changes: List<PointerInputChange>):
+ private fun dispatchToView(pointerEvent: PointerEvent):
List<PointerInputChange> {
- @Suppress("NAME_SHADOWING")
- var changes = changes
-
- // TODO(b/158034713): This should likely not be the view's location in window, but
- // instead should take the global position of this PointerInteropFilter.
- // Depending on future work, this may or may not be the case.
- val globalToLocalOffset =
- reusableLocationInWindow.run {
- view.getLocationInWindow(this)
- IntOffset(this[0], this[1])
- }
+ var changes = pointerEvent.changes
if (changes.fastAny { it.anyChangeConsumed() }) {
// We should no longer dispatch to the Android View.
if (state === DispatchToViewState.Dispatching) {
- // If we were dipatching, send ACTION_CANCEL.
- changes.toCancelMotionEventScope(globalToLocalOffset) { motionEvent ->
+ // If we were dispatching, send ACTION_CANCEL.
+ pointerEvent.toCancelMotionEventScope(
+ Offset(view.x, view.y)
+ ) { motionEvent ->
view.dispatchTouchEvent(motionEvent)
}
}
state = DispatchToViewState.NotDispatching
} else {
// Dispatch and update our state with the result.
-
- changes.toMotionEventScope(globalToLocalOffset) { motionEvent ->
+ pointerEvent.toMotionEventScope(Offset(view.x, view.y)) { motionEvent ->
state = if (view.dispatchTouchEvent(motionEvent)) {
DispatchToViewState.Dispatching
} else {
diff --git a/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropUtils.kt b/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropUtils.kt
index baa8a1c..a71b846 100644
--- a/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropUtils.kt
+++ b/ui/ui-core/src/androidMain/kotlin/androidx/ui/node/PointerInteropUtils.kt
@@ -19,47 +19,37 @@
import android.os.SystemClock
import android.view.InputDevice
import android.view.MotionEvent
-import androidx.ui.core.PointerInputChange
-import androidx.ui.core.changedToDownIgnoreConsumed
-import androidx.ui.core.changedToUpIgnoreConsumed
+import android.view.MotionEvent.ACTION_CANCEL
+import androidx.ui.core.PointerEvent
+import androidx.ui.geometry.Offset
import androidx.ui.unit.Duration
-import androidx.ui.unit.IntOffset
import androidx.ui.unit.NanosecondsPerMillisecond
import androidx.ui.unit.milliseconds
-// TODO(shepshapard): Refactor in order to remove the need for current.uptime!!
/**
- * Converts to a [MotionEvent], runs [block] with it, and recycles the [MotionEvent].
+ * Converts to a [MotionEvent] and runs [block] with it.
*
- * @param regionToGlobalOffset The global offset of the region where this [MotionEvent] is being
- * used. This will be added to each [PointerInputChange]'s position in order set raw coordinates
- * correctly, and will be subtracted via [MotionEvent.offsetLocation] so the [MotionEvent]
- * is still offset to be relative to the region.
- * @param block The block to be executed with the created [MotionEvent].
+ * @param offset The offset to be applied to the resulting [MotionEvent].
+ * @param block The block to be executed with the resulting [MotionEvent].
*/
-internal fun List<PointerInputChange>.toMotionEventScope(
- regionToGlobalOffset: IntOffset,
+internal fun PointerEvent.toMotionEventScope(
+ offset: Offset,
block: (MotionEvent) -> Unit
) {
- toMotionEventScope(regionToGlobalOffset, block, false)
+ toMotionEventScope(offset, block, false)
}
/**
- * Converts to an [MotionEvent.ACTION_CANCEL] [MotionEvent], runs [block] with it, and recycles the
- * [MotionEvent].
+ * Converts to an [MotionEvent.ACTION_CANCEL] [MotionEvent] and runs [block] with it.
*
- * @param regionToGlobalOffset The global offset of the region where this [MotionEvent] is being
- * used. This will be added to each [PointerInputChange]'s position in order set raw coordinates
- * correctly, and will be subtracted via [MotionEvent.offsetLocation] so the [MotionEvent]
- * is still offset to be relative to the region.
- * @param block The block to be executed with the created [MotionEvent].
+ * @param offset The offset to be applied to the resulting [MotionEvent].
+ * @param block The block to be executed with the resulting [MotionEvent].
*/
-// TODO(shepshapard): Refactor in order to remove the need for current.uptime!!
-internal fun List<PointerInputChange>.toCancelMotionEventScope(
- regionToGlobalOffset: IntOffset,
+internal fun PointerEvent.toCancelMotionEventScope(
+ offset: Offset,
block: (MotionEvent) -> Unit
) {
- toMotionEventScope(regionToGlobalOffset, block, true)
+ toMotionEventScope(offset, block, true)
}
internal fun emptyCancelMotionEventScope(
@@ -69,111 +59,33 @@
// Does what ViewGroup does when it needs to send a minimal ACTION_CANCEL event.
val nowMillis = now.nanoseconds / NanosecondsPerMillisecond
val motionEvent =
- MotionEvent.obtain(nowMillis, nowMillis, MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0)
- motionEvent.source = InputDevice.SOURCE_TOUCHSCREEN
+ MotionEvent.obtain(nowMillis, nowMillis, ACTION_CANCEL, 0.0f, 0.0f, 0)
+ motionEvent.source = InputDevice.SOURCE_UNKNOWN
block(motionEvent)
motionEvent.recycle()
}
-private fun List<PointerInputChange>.toMotionEventScope(
- regionToGlobalOffset: IntOffset,
+private fun PointerEvent.toMotionEventScope(
+ offset: Offset,
block: (MotionEvent) -> Unit,
cancel: Boolean
) {
- // We need to make sure this is not empty
- check(isNotEmpty())
+ requireNotNull(motionEvent) {
+ "The PointerEvent receiver cannot have a null MotionEvent."
+ }
- // We derive the values of each aspect of MotionEvent...
-
- val eventTime =
- first().current.uptime!!.nanoseconds / NanosecondsPerMillisecond
-
- val action = if (cancel) {
- MotionEvent.ACTION_CANCEL
- } else {
- if (all { it.changedToDownIgnoreConsumed() }) {
- createAction(MotionEvent.ACTION_DOWN, 0)
- } else if (all { it.changedToUpIgnoreConsumed() }) {
- createAction(MotionEvent.ACTION_UP, 0)
- } else {
- val downIndex = indexOfFirst { it.changedToDownIgnoreConsumed() }
- if (downIndex != -1) {
- createAction(MotionEvent.ACTION_POINTER_DOWN, downIndex)
- } else {
- val upIndex = indexOfFirst { it.changedToUpIgnoreConsumed() }
- if (upIndex != -1) {
- createAction(MotionEvent.ACTION_POINTER_UP, upIndex)
- } else {
- createAction(MotionEvent.ACTION_MOVE, 0)
- }
- }
+ motionEvent.apply {
+ val oldAction = action
+ if (cancel) {
+ action = ACTION_CANCEL
}
- }
- val numPointers = size
+ offsetLocation(-offset.x, -offset.y)
- // TODO(b/154136736): "(it.id.value % 32).toInt()" is very fishy, but android never expects
- // the id to be larger than 31.
- val pointerProperties =
- map {
- MotionEvent.PointerProperties().apply {
- id = (it.id.value % 32).toInt()
- toolType = MotionEvent.TOOL_TYPE_UNKNOWN
- }
- }.toTypedArray()
-
- val pointerCoords =
- map {
- val offsetX =
- if (it.changedToUpIgnoreConsumed()) {
- it.previous.position!!.x
- } else {
- it.current.position!!.x
- }
- val offsetY =
- if (it.changedToUpIgnoreConsumed()) {
- it.previous.position!!.y
- } else {
- it.current.position!!.y
- }
- // We add the regionToGlobalOffset so that the raw coordinates are correct.
- val rawX = offsetX + regionToGlobalOffset.x
- val rawY = offsetY + regionToGlobalOffset.y
-
- MotionEvent.PointerCoords().apply {
- this.x = rawX
- this.y = rawY
- }
- }.toTypedArray()
-
- // ... Then we create the MotionEvent, dispatch it to block, and recycle it.
-
- // TODO(b/154136736): Downtime as 0 isn't right. Not sure it matters.
- MotionEvent.obtain(
- 0,
- eventTime,
- action,
- numPointers,
- pointerProperties,
- pointerCoords,
- 0,
- 0,
- 0f,
- 0f,
- 0,
- 0,
- 0,
- 0
- ).apply {
- // We subtract the regionToGlobalOffset so the local coordinates are correct.
- offsetLocation(
- -regionToGlobalOffset.x.toFloat(),
- -regionToGlobalOffset.y.toFloat()
- )
block(this)
- recycle()
- }
-}
-private fun createAction(actionType: Int, actionIndex: Int) =
- actionType + (actionIndex shl MotionEvent.ACTION_POINTER_INDEX_SHIFT)
+ offsetLocation(offset.x, offset.y)
+
+ action = oldAction
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/PointerInput.kt b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/PointerInput.kt
index 87b77d4..25d1a58 100644
--- a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/PointerInput.kt
+++ b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/PointerInput.kt
@@ -18,6 +18,7 @@
import androidx.compose.Immutable
import androidx.compose.Stable
+import androidx.ui.core.pointerinput.PointerInputEvent
import androidx.ui.geometry.Offset
import androidx.ui.unit.IntSize
import androidx.ui.unit.Uptime
@@ -29,20 +30,30 @@
* it is efficient to split the changes between those that are relevant to the sub tree and those
* that are not.
*/
-internal data class InternalPointerEvent(
+internal expect class InternalPointerEvent(
+ changes: MutableMap<PointerId, PointerInputChange>,
+ pointerInputEvent: PointerInputEvent
+) {
var changes: MutableMap<PointerId, PointerInputChange>
-)
+}
/**
* Describes a pointer input change event that has occurred at a particular point in time.
- *
- * Right now this just contains a list of [PointerInputChange]s but as refactoring continues,
- * will contain more data that is global to the change, such as the current [Uptime] and the
- * [Uptime] of the previous [PointerEvent].
*/
-data class PointerEvent(
+expect class PointerEvent internal constructor(
+ changes: List<PointerInputChange>,
+ internalPointerEvent: InternalPointerEvent?
+) {
+ /**
+ * @param changes The changes.
+ */
+ constructor(changes: List<PointerInputChange>)
+
+ /**
+ * The changes.
+ */
val changes: List<PointerInputChange>
-)
+}
/**
* Describes a change that has occurred for a particular pointer, as well as how much of the change
diff --git a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/HitPathTracker.kt b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/HitPathTracker.kt
index 380629e..02cdc4b 100644
--- a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/HitPathTracker.kt
+++ b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/HitPathTracker.kt
@@ -19,10 +19,10 @@
import androidx.ui.core.CustomEvent
import androidx.ui.core.CustomEventDispatcher
import androidx.ui.core.InternalPointerEvent
+import androidx.ui.core.PointerEvent
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerId
import androidx.ui.core.PointerInputChange
-import androidx.ui.core.PointerEvent
import androidx.ui.unit.IntOffset
import androidx.ui.unit.IntSize
import androidx.ui.unit.plus
@@ -539,7 +539,8 @@
pass: PointerEventPass,
size: IntSize
) {
- filter.onPointerEvent(toPointerEvent(), pass, size).forEach {
+ val pointerEvent = PointerEvent(this.changes.values.toList(), this)
+ filter.onPointerEvent(pointerEvent, pass, size).forEach {
this.changes[it.id] = it
}
}
@@ -562,8 +563,6 @@
addOffset(-position)
}
- private fun InternalPointerEvent.toPointerEvent() = PointerEvent(changes.values.toList())
-
private inline fun <K, V> MutableMap<K, V>.replaceEverything(f: (V) -> V) {
for (entry in this) {
entry.setValue(f(entry.value))
diff --git a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt
index 3ac46db..e72a8e0 100644
--- a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt
+++ b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEvent.kt
@@ -26,17 +26,17 @@
*
* All pointer locations are relative to the device screen.
*/
-internal data class PointerInputEvent(
- val uptime: Uptime,
+internal expect class PointerInputEvent {
+ val uptime: Uptime
val pointers: List<PointerInputEventData>
-)
+}
/**
* Data that describes a particular pointer
*
* All pointer locations are relative to the device screen.
*/
-data class PointerInputEventData(
+internal data class PointerInputEventData(
val id: PointerId,
val pointerInputData: PointerInputData
)
diff --git a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
index 9f0c333..1ec35d2 100644
--- a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
+++ b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/pointerinput/PointerInputEventProcessor.kt
@@ -132,7 +132,7 @@
previousPointerInputData.remove(it.id)
}
}
- return InternalPointerEvent(changes)
+ return InternalPointerEvent(changes, pointerInputEvent)
}
/**