Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiTouch tests #359

Merged
merged 1 commit into from
Jan 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/src/androidTest/java/info/touchimage/demo/TouchTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import info.touchimage.demo.utils.MultiTouchDownEvent
import info.touchimage.demo.utils.TouchAction
import org.junit.Rule
import org.junit.Test
Expand All @@ -31,4 +32,15 @@ class TouchTest {
.writeToTestStorage("${javaClass.simpleName}_${nameRule.methodName}-touch2")
}

@Test
fun testMultiTouch() {
val touchList: Array<Pair<Float, Float>> = listOf(
Pair(4f, 8f),
Pair(40f, 80f),
Pair(30f, 70f)
).toTypedArray()
onView(withId(R.id.imageSingle)).perform(MultiTouchDownEvent(touchList))
takeScreenshot()
.writeToTestStorage("${javaClass.simpleName}_${nameRule.methodName}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package info.touchimage.demo.utils

import android.os.SystemClock
import android.view.InputDevice
import android.view.MotionEvent
import android.view.View
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import org.hamcrest.Matcher

class MultiTouchDownEvent(private val locations: Array<Pair<Float, Float>>) : ViewAction {

override fun getDescription() = "Multi Touch Event"

override fun getConstraints(): Matcher<View> = isDisplayed()

override fun perform(uiController: UiController, view: View) {

val screenPos = IntArray(2)
view.getLocationOnScreen(screenPos)

val coordinatesList = buildCoordinatesList(screenPos)
val pointerProperties = buildPointerPropertiesList()
println(coordinatesList)
val downTime = SystemClock.uptimeMillis()
val eventTime = SystemClock.uptimeMillis()

for (i in coordinatesList.indices) {
val pointerCount = i + 1

val coordinatesSlice = coordinatesList.subList(0, pointerCount)
val propertiesSlice = pointerProperties.subList(0, pointerCount)

val eventType = pointerDownEventType(pointerCount)

val event = MotionEvent.obtain(
downTime,
eventTime,
eventType,
pointerCount,
propertiesSlice.toTypedArray(),
coordinatesSlice.toTypedArray(),
0,
0,
1f,
1f,
0,
0,
InputDevice.SOURCE_UNKNOWN,
0
)

uiController.injectMotionEvent(event)

event.recycle()
}
}

private fun buildCoordinatesList(screenPosition: IntArray): List<MotionEvent.PointerCoords> {
return locations.map {
val coordinate = MotionEvent.PointerCoords()
coordinate.x = it.first + screenPosition[0]
coordinate.y = it.second + screenPosition[1]


coordinate.pressure = 1f
coordinate.size = 1f
coordinate
}
}

private fun buildPointerPropertiesList(): List<MotionEvent.PointerProperties> {
return IntArray(locations.count()) { it }.map {
val pointer = MotionEvent.PointerProperties()
pointer.id = it
pointer
}
}

private fun pointerDownEventType(numberOfPointers: Int): Int {
if (numberOfPointers < 1) return -1

var eventType = if (numberOfPointers == 1) MotionEvent.ACTION_DOWN else MotionEvent.ACTION_POINTER_DOWN
eventType += (numberOfPointers shl MotionEvent.ACTION_POINTER_INDEX_SHIFT)

return eventType
}
}