blob: 06a02193e9d8b09824d31bb1bb5f864130b46ec1 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view.cts;
import static android.view.cts.MotionEventUtils.withCoords;
import static android.view.cts.MotionEventUtils.withProperties;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.graphics.Matrix;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import android.view.cts.MotionEventUtils.PointerCoordsBuilder;
import android.view.cts.MotionEventUtils.PointerPropertiesBuilder;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Test {@link MotionEvent}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
public class MotionEventTest {
private MotionEvent mMotionEvent1;
private MotionEvent mMotionEvent2;
private MotionEvent mMotionEventDynamic;
private long mDownTime;
private long mEventTime;
private static final float X_3F = 3.0f;
private static final float Y_4F = 4.0f;
private static final int META_STATE = KeyEvent.META_SHIFT_ON;
private static final float PRESSURE_1F = 1.0f;
private static final float SIZE_1F = 1.0f;
private static final float X_PRECISION_3F = 3.0f;
private static final float Y_PRECISION_4F = 4.0f;
private static final int DEVICE_ID_1 = 1;
private static final int EDGE_FLAGS = MotionEvent.EDGE_TOP;
private static final float DELTA = 0.01f;
private static final float RAW_COORD_TOLERANCE = 0.001f;
private static native void nativeMotionEventTest(MotionEvent event);
static {
System.loadLibrary("ctsview_jni");
}
@Before
public void setup() {
mDownTime = SystemClock.uptimeMillis();
mEventTime = SystemClock.uptimeMillis();
mMotionEvent1 = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, X_3F, Y_4F, META_STATE);
mMotionEvent2 = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, X_3F, Y_4F, PRESSURE_1F, SIZE_1F, META_STATE,
X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS);
}
@After
public void teardown() {
if (null != mMotionEvent1) {
mMotionEvent1.recycle();
}
if (null != mMotionEvent2) {
mMotionEvent2.recycle();
}
if (null != mMotionEventDynamic) {
mMotionEventDynamic.recycle();
}
}
@Test
public void testObtainBasic() {
mMotionEvent1 = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_DOWN, X_3F, Y_4F, META_STATE);
assertNotNull(mMotionEvent1);
assertEquals(mDownTime, mMotionEvent1.getDownTime());
assertEquals(mEventTime, mMotionEvent1.getEventTime());
assertEquals(MotionEvent.ACTION_DOWN, mMotionEvent1.getAction());
assertEquals(X_3F, mMotionEvent1.getX(), DELTA);
assertEquals(Y_4F, mMotionEvent1.getY(), DELTA);
assertEquals(X_3F, mMotionEvent1.getRawX(), DELTA);
assertEquals(Y_4F, mMotionEvent1.getRawY(), DELTA);
assertEquals(META_STATE, mMotionEvent1.getMetaState());
assertEquals(0, mMotionEvent1.getDeviceId());
assertEquals(0, mMotionEvent1.getEdgeFlags());
assertEquals(PRESSURE_1F, mMotionEvent1.getPressure(), DELTA);
assertEquals(SIZE_1F, mMotionEvent1.getSize(), DELTA);
assertEquals(1.0f, mMotionEvent1.getXPrecision(), DELTA);
assertEquals(1.0f, mMotionEvent1.getYPrecision(), DELTA);
}
@Test
public void testObtainFromMotionEvent() {
mMotionEventDynamic = MotionEvent.obtain(mMotionEvent2);
assertNotNull(mMotionEventDynamic);
assertEquals(mMotionEvent2.getDownTime(), mMotionEventDynamic.getDownTime());
assertEquals(mMotionEvent2.getEventTime(), mMotionEventDynamic.getEventTime());
assertEquals(mMotionEvent2.getAction(), mMotionEventDynamic.getAction());
assertEquals(mMotionEvent2.getX(), mMotionEventDynamic.getX(), DELTA);
assertEquals(mMotionEvent2.getY(), mMotionEventDynamic.getY(), DELTA);
assertEquals(mMotionEvent2.getX(), mMotionEventDynamic.getRawX(), DELTA);
assertEquals(mMotionEvent2.getY(), mMotionEventDynamic.getRawY(), DELTA);
assertEquals(mMotionEvent2.getMetaState(), mMotionEventDynamic.getMetaState());
assertEquals(mMotionEvent2.getDeviceId(), mMotionEventDynamic.getDeviceId());
assertEquals(mMotionEvent2.getEdgeFlags(), mMotionEventDynamic.getEdgeFlags());
assertEquals(mMotionEvent2.getPressure(), mMotionEventDynamic.getPressure(), DELTA);
assertEquals(mMotionEvent2.getSize(), mMotionEventDynamic.getSize(), DELTA);
assertEquals(mMotionEvent2.getXPrecision(), mMotionEventDynamic.getXPrecision(), DELTA);
assertEquals(mMotionEvent2.getYPrecision(), mMotionEventDynamic.getYPrecision(), DELTA);
}
@Test
public void testObtainAllFields() {
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_DOWN, X_3F, Y_4F, PRESSURE_1F, SIZE_1F, META_STATE,
X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS);
assertNotNull(mMotionEventDynamic);
assertEquals(mDownTime, mMotionEventDynamic.getDownTime());
assertEquals(mEventTime, mMotionEventDynamic.getEventTime());
assertEquals(MotionEvent.ACTION_DOWN, mMotionEventDynamic.getAction());
assertEquals(X_3F, mMotionEventDynamic.getX(), DELTA);
assertEquals(Y_4F, mMotionEventDynamic.getY(), DELTA);
assertEquals(X_3F, mMotionEventDynamic.getRawX(), DELTA);
assertEquals(Y_4F, mMotionEventDynamic.getRawY(), DELTA);
assertEquals(META_STATE, mMotionEventDynamic.getMetaState());
assertEquals(DEVICE_ID_1, mMotionEventDynamic.getDeviceId());
assertEquals(EDGE_FLAGS, mMotionEventDynamic.getEdgeFlags());
assertEquals(PRESSURE_1F, mMotionEventDynamic.getPressure(), DELTA);
assertEquals(SIZE_1F, mMotionEventDynamic.getSize(), DELTA);
assertEquals(X_PRECISION_3F, mMotionEventDynamic.getXPrecision(), DELTA);
assertEquals(Y_PRECISION_4F, mMotionEventDynamic.getYPrecision(), DELTA);
}
@Test
public void testObtainFromPropertyArrays() {
PointerCoordsBuilder coordsBuilder0 =
withCoords(X_3F, Y_4F).withPressure(PRESSURE_1F).withSize(SIZE_1F).
withTool(1.2f, 1.4f).withGenericAxis1(2.6f);
PointerCoordsBuilder coordsBuilder1 =
withCoords(X_3F + 1.0f, Y_4F - 2.0f).withPressure(PRESSURE_1F + 0.2f).
withSize(SIZE_1F + 0.5f).withTouch(2.2f, 0.6f).withGenericAxis1(2.6f);
PointerPropertiesBuilder propertiesBuilder0 =
withProperties(0, MotionEvent.TOOL_TYPE_FINGER);
PointerPropertiesBuilder propertiesBuilder1 =
withProperties(1, MotionEvent.TOOL_TYPE_FINGER);
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, 2,
new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() },
new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() },
META_STATE, 0, X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS,
InputDevice.SOURCE_TOUCHSCREEN, 0);
// We expect to have data for two pointers
assertEquals(2, mMotionEventDynamic.getPointerCount());
assertEquals(0, mMotionEventDynamic.getPointerId(0));
assertEquals(1, mMotionEventDynamic.getPointerId(1));
assertEquals(0, mMotionEventDynamic.getFlags());
verifyCurrentPointerData(mMotionEventDynamic,
new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 },
new PointerCoordsBuilder[] { coordsBuilder0, coordsBuilder1 });
}
@Test
public void testObtainNoHistory() {
// Add two batch to one of our events
mMotionEvent2.addBatch(mEventTime + 10, X_3F + 5.0f, Y_4F + 5.0f, 0.5f, 0.5f, 0);
mMotionEvent2.addBatch(mEventTime + 20, X_3F + 10.0f, Y_4F + 15.0f, 2.0f, 3.0f, 0);
// The newly added batch should be the "new" values of the event
withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f).
verifyMatches(mMotionEvent2);
assertEquals(mEventTime + 20, mMotionEvent2.getEventTime());
// We should have history with 2 entries
assertEquals(2, mMotionEvent2.getHistorySize());
// The previous data should be history at index 1
withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f).
verifyMatchesHistorical(mMotionEvent2, 1);
assertEquals(mEventTime + 10, mMotionEvent2.getHistoricalEventTime(1));
// And the original data should be history at index 0
withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f).
verifyMatchesHistorical(mMotionEvent2, 0);
assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0));
assertEquals(2, mMotionEvent2.getHistorySize());
mMotionEventDynamic = MotionEvent.obtainNoHistory(mMotionEvent2);
// The newly obtained event should have the matching current content
withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f).
verifyMatches(mMotionEvent2);
// And no history
assertEquals(0, mMotionEventDynamic.getHistorySize());
}
@Test
public void testAccessAction() {
assertEquals(MotionEvent.ACTION_MOVE, mMotionEvent1.getAction());
mMotionEvent1.setAction(MotionEvent.ACTION_UP);
assertEquals(MotionEvent.ACTION_UP, mMotionEvent1.getAction());
mMotionEvent1.setAction(MotionEvent.ACTION_MOVE);
assertEquals(MotionEvent.ACTION_MOVE, mMotionEvent1.getAction());
mMotionEvent1.setAction(MotionEvent.ACTION_CANCEL);
assertEquals(MotionEvent.ACTION_CANCEL, mMotionEvent1.getAction());
mMotionEvent1.setAction(MotionEvent.ACTION_DOWN);
assertEquals(MotionEvent.ACTION_DOWN, mMotionEvent1.getAction());
}
@Test
public void testDescribeContents() {
// make sure this method never throw any exception.
mMotionEvent2.describeContents();
}
@Test
public void testAccessEdgeFlags() {
assertEquals(EDGE_FLAGS, mMotionEvent2.getEdgeFlags());
int edgeFlags = 10;
mMotionEvent2.setEdgeFlags(edgeFlags);
assertEquals(edgeFlags, mMotionEvent2.getEdgeFlags());
}
@Test
public void testWriteToParcel() {
Parcel parcel = Parcel.obtain();
mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
parcel.setDataPosition(0);
MotionEvent motionEvent = MotionEvent.CREATOR.createFromParcel(parcel);
assertEquals(mMotionEvent2.getRawY(), motionEvent.getRawY(), DELTA);
assertEquals(mMotionEvent2.getRawX(), motionEvent.getRawX(), DELTA);
assertEquals(mMotionEvent2.getY(), motionEvent.getY(), DELTA);
assertEquals(mMotionEvent2.getX(), motionEvent.getX(), DELTA);
assertEquals(mMotionEvent2.getAction(), motionEvent.getAction());
assertEquals(mMotionEvent2.getDownTime(), motionEvent.getDownTime());
assertEquals(mMotionEvent2.getEventTime(), motionEvent.getEventTime());
assertEquals(mMotionEvent2.getEdgeFlags(), motionEvent.getEdgeFlags());
assertEquals(mMotionEvent2.getDeviceId(), motionEvent.getDeviceId());
}
@Test
public void testReadFromParcelWithInvalidPointerCountSize() {
Parcel parcel = Parcel.obtain();
mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
// Move to pointer id count.
parcel.setDataPosition(4);
parcel.writeInt(17);
parcel.setDataPosition(0);
try {
MotionEvent.CREATOR.createFromParcel(parcel);
fail("deserialized invalid parcel");
} catch (RuntimeException e) {
// Expected.
}
}
@Test
public void testReadFromParcelWithInvalidSampleSize() {
Parcel parcel = Parcel.obtain();
mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
// Move to sample count.
parcel.setDataPosition(2 * 4);
parcel.writeInt(0x000f0000);
parcel.setDataPosition(0);
try {
MotionEvent.CREATOR.createFromParcel(parcel);
fail("deserialized invalid parcel");
} catch (RuntimeException e) {
// Expected.
}
}
@Test
public void testToString() {
// make sure this method never throw exception.
mMotionEvent2.toString();
}
@Test
public void testOffsetLocationForPointerSource() {
assertEquals(X_3F, mMotionEvent2.getX(), DELTA);
assertEquals(Y_4F, mMotionEvent2.getY(), DELTA);
mMotionEvent2.setSource(InputDevice.SOURCE_TOUCHSCREEN);
float offsetX = 1.0f;
float offsetY = 1.0f;
mMotionEvent2.offsetLocation(offsetX, offsetY);
withCoords(X_3F + offsetX, Y_4F + offsetY)
.withPressure(PRESSURE_1F)
.withSize(SIZE_1F)
.verifyMatches(mMotionEvent2);
}
@Test
public void testNoLocationOffsetForNonPointerSource() {
assertEquals(X_3F, mMotionEvent2.getX(), DELTA);
assertEquals(Y_4F, mMotionEvent2.getY(), DELTA);
mMotionEvent2.setSource(InputDevice.SOURCE_TOUCHPAD);
float offsetX = 1.0f;
float offsetY = 1.0f;
mMotionEvent2.offsetLocation(offsetX, offsetY);
withCoords(X_3F, Y_4F)
.withPressure(PRESSURE_1F)
.withSize(SIZE_1F)
.verifyMatches(mMotionEvent2);
}
@Test
public void testSetLocation() {
assertEquals(X_3F, mMotionEvent2.getX(), DELTA);
assertEquals(Y_4F, mMotionEvent2.getY(), DELTA);
mMotionEvent2.setSource(InputDevice.SOURCE_TOUCHSCREEN);
mMotionEvent2.setLocation(0.0f, 0.0f);
withCoords(0.0f, 0.0f).withPressure(PRESSURE_1F).withSize(SIZE_1F).
verifyMatches(mMotionEvent2);
mMotionEvent2.setLocation(2.0f, 2.0f);
withCoords(2.0f, 2.0f).withPressure(PRESSURE_1F).withSize(SIZE_1F).
verifyMatches(mMotionEvent2);
}
@Test
public void testGetHistoricalData() {
assertEquals(0, mMotionEvent2.getHistorySize());
mMotionEvent2.addBatch(mEventTime + 10, X_3F + 5.0f, Y_4F + 5.0f, 0.5f, 0.5f, 0);
// The newly added batch should be the "new" values of the event
withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f).
verifyMatches(mMotionEvent2);
assertEquals(mEventTime + 10, mMotionEvent2.getEventTime());
// We should have history with 1 entry
assertEquals(1, mMotionEvent2.getHistorySize());
// And the previous / original data should be history at index 0
assertEquals(1, mMotionEvent2.getHistorySize());
withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f).
verifyMatchesHistorical(mMotionEvent2, 0);
assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0));
// Add another update batch to our event
mMotionEvent2.addBatch(mEventTime + 20, X_3F + 10.0f, Y_4F + 15.0f, 2.0f, 3.0f, 0);
// The newly added batch should be the "new" values of the event
withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f).
verifyMatches(mMotionEvent2);
assertEquals(mEventTime + 20, mMotionEvent2.getEventTime());
// We should have history with 2 entries
assertEquals(2, mMotionEvent2.getHistorySize());
// The previous data should be history at index 1
withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f).
verifyMatchesHistorical(mMotionEvent2, 1);
assertEquals(mEventTime + 10, mMotionEvent2.getHistoricalEventTime(1));
// And the original data should be history at index 0
withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f).
verifyMatchesHistorical(mMotionEvent2, 0);
assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0));
}
private static void verifyCurrentPointerData(MotionEvent motionEvent,
PointerPropertiesBuilder[] pointerPropertiesBuilders,
PointerCoordsBuilder[] pointerCoordsBuilders) {
assertNotNull(motionEvent);
assertNotNull(pointerPropertiesBuilders);
assertNotNull(pointerCoordsBuilders);
final int pointerCount = motionEvent.getPointerCount();
assertEquals(pointerCount, pointerPropertiesBuilders.length);
assertEquals(pointerCount, pointerCoordsBuilders.length);
// Test that we have the expected data fetched via MotionEvent.getPointerCoords API
for (int i = 0; i < pointerCount; i++) {
pointerCoordsBuilders[i].verifyMatchesPointerCoords(motionEvent, i);
}
// Test that we have the expected data fetched via per-field MotionEvent getter APIs
for (int i = 0; i < pointerCount; i++) {
pointerCoordsBuilders[i].verifyMatches(motionEvent, i);
}
// Test that we have the expected data fetched via MotionEvent.getPointerProperties API
for (int i = 0; i < pointerCount; i++) {
pointerPropertiesBuilders[i].verifyMatchesPointerProperties(motionEvent, i);
}
// Test that we have the expected data fetched via per-field MotionEvent getter APIs
for (int i = 0; i < pointerCount; i++) {
pointerPropertiesBuilders[i].verifyMatches(motionEvent, i);
}
}
private static void verifyHistoricalPointerData(MotionEvent motionEvent,
PointerCoordsBuilder[] pointerCoordsBuilders, int pos) {
assertNotNull(motionEvent);
assertNotNull(pointerCoordsBuilders);
final int pointerCount = motionEvent.getPointerCount();
assertEquals(pointerCount, pointerCoordsBuilders.length);
// Test that we have the expected data fetched via MotionEvent.getHistoricalPointerCoords
// API
for (int i = 0; i < pointerCount; i++) {
pointerCoordsBuilders[i].verifyMatchesHistoricalPointerCoords(motionEvent, i, pos);
}
// Test that we have the expected data fetched via per-field MotionEvent getter APIs
for (int i = 0; i < pointerCount; i++) {
pointerCoordsBuilders[i].verifyMatchesHistorical(motionEvent, i, pos);
}
}
@Test
public void testGetCurrentDataWithTwoPointers() {
PointerCoordsBuilder coordsBuilder0 =
withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f,
1.4f).withGenericAxis1(4.4f);
PointerCoordsBuilder coordsBuilder1 =
withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTouch(2.2f,
0.6f).withGenericAxis1(6.6f);
PointerPropertiesBuilder propertiesBuilder0 =
withProperties(0, MotionEvent.TOOL_TYPE_FINGER);
PointerPropertiesBuilder propertiesBuilder1 =
withProperties(1, MotionEvent.TOOL_TYPE_FINGER);
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, 2,
new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() },
new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() },
0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
// We expect to have data for two pointers
assertEquals(2, mMotionEventDynamic.getPointerCount());
assertEquals(0, mMotionEventDynamic.getPointerId(0));
assertEquals(1, mMotionEventDynamic.getPointerId(1));
assertEquals(0, mMotionEventDynamic.getFlags());
verifyCurrentPointerData(mMotionEventDynamic,
new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 },
new PointerCoordsBuilder[] { coordsBuilder0, coordsBuilder1 });
}
/**
* Verify we can get raw coordinates for specific pointers using MotionEvent#getRawX(int) and
* MotionEvent#getRawY(int). Also verity MotionEvent#getRawX() and MotionEvent#getRawY()
* returns the raw coordinates of pointer with pointer index 0.
*/
@Test
public void testGetRawCoordsWithTwoPointers() {
PointerCoordsBuilder coordsBuilder0 =
withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f,
1.4f).withGenericAxis1(4.4f);
PointerCoordsBuilder coordsBuilder1 =
withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTouch(2.2f,
0.6f).withGenericAxis1(6.6f);
PointerPropertiesBuilder propertiesBuilder0 =
withProperties(0, MotionEvent.TOOL_TYPE_FINGER);
PointerPropertiesBuilder propertiesBuilder1 =
withProperties(1, MotionEvent.TOOL_TYPE_FINGER);
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, 2,
new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() },
new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() },
0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
assertEquals(10.0f, mMotionEventDynamic.getRawX(), RAW_COORD_TOLERANCE);
assertEquals(20.0f, mMotionEventDynamic.getRawY(), RAW_COORD_TOLERANCE);
// Assert that getRawX returns the results for the first pointer index.
assertEquals(mMotionEventDynamic.getRawX(), mMotionEventDynamic.getRawX(0),
RAW_COORD_TOLERANCE);
assertEquals(mMotionEventDynamic.getRawY(), mMotionEventDynamic.getRawY(0),
RAW_COORD_TOLERANCE);
assertEquals(30.0f, mMotionEventDynamic.getRawX(1), RAW_COORD_TOLERANCE);
assertEquals(40.0f, mMotionEventDynamic.getRawY(1), RAW_COORD_TOLERANCE);
}
@Test
public void testGetHistoricalDataWithTwoPointers() {
// PHASE 1 - construct the initial data for the event
PointerCoordsBuilder coordsBuilderInitial0 =
withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f, 1.4f).
withTouch(0.7f, 0.6f).withOrientation(2.0f).withGenericAxis1(4.4f);
PointerCoordsBuilder coordsBuilderInitial1 =
withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTool(1.3f, 1.7f).
withTouch(2.7f, 3.6f).withOrientation(1.0f).withGenericAxis1(5.4f);
PointerPropertiesBuilder propertiesBuilder0 =
withProperties(0, MotionEvent.TOOL_TYPE_FINGER);
PointerPropertiesBuilder propertiesBuilder1 =
withProperties(1, MotionEvent.TOOL_TYPE_FINGER);
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_MOVE, 2,
new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() },
new PointerCoords[] {
coordsBuilderInitial0.build(), coordsBuilderInitial1.build() },
0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
// We expect to have data for two pointers
assertEquals(2, mMotionEventDynamic.getPointerCount());
assertEquals(0, mMotionEventDynamic.getPointerId(0));
assertEquals(1, mMotionEventDynamic.getPointerId(1));
assertEquals(0, mMotionEventDynamic.getFlags());
verifyCurrentPointerData(mMotionEventDynamic,
new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 },
new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 });
// PHASE 2 - add a new batch of data to our event
PointerCoordsBuilder coordsBuilderNext0 =
withCoords(15.0f, 25.0f).withPressure(1.6f).withSize(2.2f).withTool(1.2f, 1.4f).
withTouch(1.0f, 0.9f).withOrientation(2.2f).withGenericAxis1(7.4f);
PointerCoordsBuilder coordsBuilderNext1 =
withCoords(35.0f, 45.0f).withPressure(1.8f).withSize(3.2f).withTool(1.2f, 1.4f).
withTouch(0.7f, 0.6f).withOrientation(2.9f).withGenericAxis1(8.4f);
mMotionEventDynamic.addBatch(mEventTime + 10,
new PointerCoords[] { coordsBuilderNext0.build(), coordsBuilderNext1.build() }, 0);
// We still expect to have data for two pointers
assertEquals(2, mMotionEventDynamic.getPointerCount());
assertEquals(0, mMotionEventDynamic.getPointerId(0));
assertEquals(1, mMotionEventDynamic.getPointerId(1));
assertEquals(0, mMotionEventDynamic.getFlags());
// The newly added batch should be the "new" values of the event
verifyCurrentPointerData(mMotionEventDynamic,
new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 },
new PointerCoordsBuilder[] { coordsBuilderNext0, coordsBuilderNext1 });
assertEquals(mEventTime + 10, mMotionEventDynamic.getEventTime());
// We should have history with 1 entry
assertEquals(1, mMotionEventDynamic.getHistorySize());
// And the previous / original data should be history at index 0
assertEquals(1, mMotionEventDynamic.getHistorySize());
verifyHistoricalPointerData(mMotionEventDynamic,
new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 },
0);
// PHASE 3 - add one more new batch of data to our event
PointerCoordsBuilder coordsBuilderLast0 =
withCoords(18.0f, 28.0f).withPressure(1.1f).withSize(2.9f).withTool(1.5f, 1.9f).
withTouch(1.2f, 5.0f).withOrientation(3.1f).withGenericAxis1(1.4f);
PointerCoordsBuilder coordsBuilderLast1 =
withCoords(38.0f, 48.0f).withPressure(1.2f).withSize(2.5f).withTool(0.2f, 0.4f).
withTouch(2.7f, 4.6f).withOrientation(0.2f).withGenericAxis1(5.4f);
mMotionEventDynamic.addBatch(mEventTime + 20,
new PointerCoords[] { coordsBuilderLast0.build(), coordsBuilderLast1.build() }, 0);
// We still expect to have data for two pointers
assertEquals(2, mMotionEventDynamic.getPointerCount());
assertEquals(0, mMotionEventDynamic.getPointerId(0));
assertEquals(1, mMotionEventDynamic.getPointerId(1));
assertEquals(0, mMotionEventDynamic.getFlags());
// The newly added batch should be the "new" values of the event
verifyCurrentPointerData(mMotionEventDynamic,
new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 },
new PointerCoordsBuilder[] { coordsBuilderLast0, coordsBuilderLast1 });
assertEquals(mEventTime + 20, mMotionEventDynamic.getEventTime());
// We should have history with 2 entries
assertEquals(2, mMotionEventDynamic.getHistorySize());
// The previous data should be history at index 1
verifyHistoricalPointerData(mMotionEventDynamic,
new PointerCoordsBuilder[] { coordsBuilderNext0, coordsBuilderNext1 },
1);
assertEquals(mEventTime + 10, mMotionEventDynamic.getHistoricalEventTime(1));
// And the original data should be history at index 0
verifyHistoricalPointerData(mMotionEventDynamic,
new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 },
0);
assertEquals(mEventTime, mMotionEventDynamic.getHistoricalEventTime(0));
}
@Test
public void testGetHistorySize() {
long eventTime = SystemClock.uptimeMillis();
float x = 10.0f;
float y = 20.0f;
float pressure = 1.0f;
float size = 1.0f;
mMotionEvent2.setAction(MotionEvent.ACTION_DOWN);
assertEquals(0, mMotionEvent2.getHistorySize());
mMotionEvent2.setAction(MotionEvent.ACTION_MOVE);
mMotionEvent2.addBatch(eventTime, x, y, pressure, size, 0);
assertEquals(1, mMotionEvent2.getHistorySize());
}
@Test
public void testRecycle() {
mMotionEvent2.setAction(MotionEvent.ACTION_MOVE);
assertEquals(0, mMotionEvent2.getHistorySize());
mMotionEvent2.addBatch(mEventTime, 10.0f, 5.0f, 1.0f, 0.0f, 0);
assertEquals(1, mMotionEvent2.getHistorySize());
mMotionEvent2.recycle();
try {
mMotionEvent2.recycle();
fail("recycle() should throw an exception when the event has already been recycled.");
} catch (RuntimeException ex) {
}
mMotionEvent2 = null; // since it was recycled, don't try to recycle again in tear down
}
@Test(expected=IllegalArgumentException.class)
public void testTransformShouldThrowWhenMatrixIsNull() {
// transform() should throw an exception when matrix is null
mMotionEvent1.transform(null);
}
@Test
public void testTransformShouldApplyMatrixToPointsAndPreserveRawPosition() {
// Generate some points on a circle, then assign each point to a pointer.
// The location of pointer 'i' is a point on a circle of radius ROTATION centered at (3,2)
// at an angle of ARC * i degrees clockwise relative to the Y axis.
// The geometrical representation is irrelevant to the test, it's just easy to generate
// and check rotation. We set the orientation to the same angle.
// Coordinate system: down is increasing Y, right is increasing X.
final float PI_180 = (float) (Math.PI / 180);
final float RADIUS = 10;
final float ARC = 36;
final float ROTATION = ARC * 2;
final int pointerCount = 11;
final int[] pointerIds = new int[pointerCount];
final PointerCoords[] pointerCoords = new PointerCoords[pointerCount];
final PointerCoords[] originalRawCoords = new PointerCoords[pointerCount];
for (int i = 0; i < pointerCount; i++) {
final PointerCoords c = new PointerCoords();
final float angle = (float) (i * ARC * PI_180);
pointerIds[i] = i;
pointerCoords[i] = c;
c.x = (float) (Math.sin(angle) * RADIUS + 3);
c.y = (float) (- Math.cos(angle) * RADIUS + 2);
c.orientation = angle;
originalRawCoords[i] = new PointerCoords(c);
}
final MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
pointerCount, pointerIds, pointerCoords, 0, 0, 0, 0, 0,
InputDevice.SOURCE_TOUCHSCREEN, 0);
dump("Original points.", event);
// Check original raw X and Y assumption.
for (int i = 0; i < pointerCount; i++) {
assertEquals(originalRawCoords[i].x, event.getRawX(i), RAW_COORD_TOLERANCE);
assertEquals(originalRawCoords[i].y, event.getRawY(i), RAW_COORD_TOLERANCE);
}
// Now translate the motion event so the circle's origin is at (0,0).
event.offsetLocation(-3, -2);
dump("Translated points.", event);
// Offsetting the location should preserve the raw X and Y of all pointers.
for (int i = 0; i < pointerCount; i++) {
assertEquals(originalRawCoords[i].x, event.getRawX(i), RAW_COORD_TOLERANCE);
assertEquals(originalRawCoords[i].y, event.getRawY(i), RAW_COORD_TOLERANCE);
}
// Apply a rotation about the origin by ROTATION degrees clockwise.
Matrix matrix = new Matrix();
matrix.setRotate(ROTATION);
event.transform(matrix);
dump("Rotated points.", event);
// Check the points.
for (int i = 0; i < pointerCount; i++) {
final PointerCoords c = pointerCoords[i];
event.getPointerCoords(i, c);
final float angle = (float) ((i * ARC + ROTATION) * PI_180);
assertEquals(Math.sin(angle) * RADIUS, c.x, RAW_COORD_TOLERANCE);
assertEquals(-Math.cos(angle) * RADIUS, c.y, RAW_COORD_TOLERANCE);
assertEquals(Math.tan(angle), Math.tan(c.orientation), 0.1);
// Applying the transformation should preserve the raw X and Y of all pointers.
assertEquals(originalRawCoords[i].x, event.getRawX(i), RAW_COORD_TOLERANCE);
assertEquals(originalRawCoords[i].y, event.getRawY(i), RAW_COORD_TOLERANCE);
}
}
private void dump(String label, MotionEvent ev) {
if (false) {
StringBuilder msg = new StringBuilder();
msg.append(label).append("\n");
msg.append(" Raw: (").append(ev.getRawX()).append(",").append(ev.getRawY()).append(")\n");
int pointerCount = ev.getPointerCount();
for (int i = 0; i < pointerCount; i++) {
msg.append(" Pointer[").append(i).append("]: (")
.append(ev.getX(i)).append(",").append(ev.getY(i)).append("), orientation=")
.append(ev.getOrientation(i) * 180 / Math.PI).append(" deg\n");
}
android.util.Log.i("TEST", msg.toString());
}
}
@Test
public void testPointerCoordsDefaultConstructor() {
PointerCoords coords = new PointerCoords();
assertEquals(0f, coords.x, 0.0f);
assertEquals(0f, coords.y, 0.0f);
assertEquals(0f, coords.pressure, 0.0f);
assertEquals(0f, coords.size, 0.0f);
assertEquals(0f, coords.touchMajor, 0.0f);
assertEquals(0f, coords.touchMinor, 0.0f);
assertEquals(0f, coords.toolMajor, 0.0f);
assertEquals(0f, coords.toolMinor, 0.0f);
assertEquals(0f, coords.orientation, 0.0f);
}
@Test
public void testPointerCoordsCopyConstructor() {
PointerCoords coords = new PointerCoords();
coords.x = 1;
coords.y = 2;
coords.pressure = 3;
coords.size = 4;
coords.touchMajor = 5;
coords.touchMinor = 6;
coords.toolMajor = 7;
coords.toolMinor = 8;
coords.orientation = 9;
coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10);
PointerCoords copy = new PointerCoords(coords);
assertEquals(1f, copy.x, 0.0f);
assertEquals(2f, copy.y, 0.0f);
assertEquals(3f, copy.pressure, 0.0f);
assertEquals(4f, copy.size, 0.0f);
assertEquals(5f, copy.touchMajor, 0.0f);
assertEquals(6f, copy.touchMinor, 0.0f);
assertEquals(7f, copy.toolMajor, 0.0f);
assertEquals(8f, copy.toolMinor, 0.0f);
assertEquals(9f, copy.orientation, 0.0f);
assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1), 0.0f);
}
@Test
public void testPointerCoordsCopyFrom() {
PointerCoords coords = new PointerCoords();
coords.x = 1;
coords.y = 2;
coords.pressure = 3;
coords.size = 4;
coords.touchMajor = 5;
coords.touchMinor = 6;
coords.toolMajor = 7;
coords.toolMinor = 8;
coords.orientation = 9;
coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10);
PointerCoords copy = new PointerCoords();
copy.copyFrom(coords);
assertEquals(1f, copy.x, 0.0f);
assertEquals(2f, copy.y, 0.0f);
assertEquals(3f, copy.pressure, 0.0f);
assertEquals(4f, copy.size, 0.0f);
assertEquals(5f, copy.touchMajor, 0.0f);
assertEquals(6f, copy.touchMinor, 0.0f);
assertEquals(7f, copy.toolMajor, 0.0f);
assertEquals(8f, copy.toolMinor, 0.0f);
assertEquals(9f, copy.orientation, 0.0f);
assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1), 0.0f);
}
@Test
public void testPointerPropertiesDefaultConstructor() {
PointerProperties properties = new PointerProperties();
assertEquals(MotionEvent.INVALID_POINTER_ID, properties.id);
assertEquals(MotionEvent.TOOL_TYPE_UNKNOWN, properties.toolType);
}
@Test
public void testPointerPropertiesCopyConstructor() {
PointerProperties properties = new PointerProperties();
properties.id = 1;
properties.toolType = MotionEvent.TOOL_TYPE_MOUSE;
PointerProperties copy = new PointerProperties(properties);
assertEquals(1, copy.id);
assertEquals(MotionEvent.TOOL_TYPE_MOUSE, copy.toolType);
}
@Test
public void testPointerPropertiesCopyFrom() {
PointerProperties properties = new PointerProperties();
properties.id = 1;
properties.toolType = MotionEvent.TOOL_TYPE_MOUSE;
PointerProperties copy = new PointerProperties();
copy.copyFrom(properties);
assertEquals(1, copy.id);
assertEquals(MotionEvent.TOOL_TYPE_MOUSE, copy.toolType);
}
@Test
public void testActionToString() {
final int[] actions = {
MotionEvent.ACTION_DOWN,
MotionEvent.ACTION_UP,
MotionEvent.ACTION_MOVE,
MotionEvent.ACTION_CANCEL,
MotionEvent.ACTION_OUTSIDE,
MotionEvent.ACTION_HOVER_MOVE,
MotionEvent.ACTION_SCROLL,
MotionEvent.ACTION_HOVER_ENTER,
MotionEvent.ACTION_HOVER_EXIT,
MotionEvent.ACTION_BUTTON_PRESS,
MotionEvent.ACTION_BUTTON_RELEASE
};
// There is no hard guarantee on the actual return result on any specific action
// from MotionEvent.actionToString. Verify that we are not crashing on those calls
// and that the return result on each is not empty
for (int i = 0; i < actions.length; i++) {
assertFalse(TextUtils.isEmpty(MotionEvent.actionToString(actions[i])));
}
final int[] pointerActions = {
MotionEvent.ACTION_POINTER_UP,
MotionEvent.ACTION_POINTER_DOWN
};
for (int i = 0; i < pointerActions.length; i++) {
for (int pointer = 0; pointer < 5; pointer++) {
int pointerAction =
pointerActions[i] | pointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
assertFalse(TextUtils.isEmpty(MotionEvent.actionToString(pointerAction)));
}
}
}
@Test
public void testAxisFromToString() {
final int[] axes = {
MotionEvent.AXIS_X,
MotionEvent.AXIS_Y,
MotionEvent.AXIS_PRESSURE,
MotionEvent.AXIS_SIZE,
MotionEvent.AXIS_TOUCH_MAJOR,
MotionEvent.AXIS_TOUCH_MINOR,
MotionEvent.AXIS_TOOL_MAJOR,
MotionEvent.AXIS_TOOL_MINOR,
MotionEvent.AXIS_ORIENTATION,
MotionEvent.AXIS_VSCROLL,
MotionEvent.AXIS_HSCROLL,
MotionEvent.AXIS_Z,
MotionEvent.AXIS_RX,
MotionEvent.AXIS_RY,
MotionEvent.AXIS_RZ,
MotionEvent.AXIS_HAT_X,
MotionEvent.AXIS_HAT_Y,
MotionEvent.AXIS_LTRIGGER,
MotionEvent.AXIS_RTRIGGER,
MotionEvent.AXIS_THROTTLE,
MotionEvent.AXIS_RUDDER,
MotionEvent.AXIS_WHEEL,
MotionEvent.AXIS_GAS,
MotionEvent.AXIS_BRAKE,
MotionEvent.AXIS_DISTANCE,
MotionEvent.AXIS_TILT,
MotionEvent.AXIS_SCROLL,
MotionEvent.AXIS_RELATIVE_X,
MotionEvent.AXIS_RELATIVE_Y,
MotionEvent.AXIS_GENERIC_1,
MotionEvent.AXIS_GENERIC_2,
MotionEvent.AXIS_GENERIC_3,
MotionEvent.AXIS_GENERIC_4,
MotionEvent.AXIS_GENERIC_5,
MotionEvent.AXIS_GENERIC_6,
MotionEvent.AXIS_GENERIC_7,
MotionEvent.AXIS_GENERIC_8,
MotionEvent.AXIS_GENERIC_9,
MotionEvent.AXIS_GENERIC_10,
MotionEvent.AXIS_GENERIC_11,
MotionEvent.AXIS_GENERIC_12,
MotionEvent.AXIS_GENERIC_13,
MotionEvent.AXIS_GENERIC_14,
MotionEvent.AXIS_GENERIC_15,
MotionEvent.AXIS_GENERIC_16
};
// There is no hard guarantee on the actual return result on any specific axis
// from MotionEvent.axisToString. Verify that we are not crashing on those calls
// and that the return result on each is not empty. However, we do expect the two-way
// call chain of to/from to get us back to the original integer value.
for (int i = 0; i < axes.length; i++) {
String axisToString = MotionEvent.axisToString(axes[i]);
assertFalse(TextUtils.isEmpty(axisToString));
assertEquals(axes[i], MotionEvent.axisFromString(axisToString));
}
}
@Test
public void testGetActionButton() {
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0);
mMotionEventDynamic.setActionButton(MotionEvent.BUTTON_STYLUS_PRIMARY);
assertEquals(MotionEvent.BUTTON_STYLUS_PRIMARY, mMotionEventDynamic.getActionButton());
mMotionEventDynamic.recycle();
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0);
mMotionEventDynamic.setActionButton(MotionEvent.BUTTON_SECONDARY);
assertEquals(MotionEvent.BUTTON_SECONDARY, mMotionEventDynamic.getActionButton());
}
@Test
public void testIsButtonPressed() {
mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_DOWN, X_3F, Y_4F, 0);
mMotionEventDynamic.setSource(InputDevice.SOURCE_MOUSE);
mMotionEventDynamic.setButtonState(
MotionEvent.BUTTON_PRIMARY | MotionEvent.BUTTON_STYLUS_PRIMARY);
assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY));
assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD));
mMotionEventDynamic.setButtonState(MotionEvent.BUTTON_PRIMARY);
assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD));
mMotionEventDynamic.setButtonState(
MotionEvent.BUTTON_FORWARD | MotionEvent.BUTTON_TERTIARY);
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY));
assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY));
assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK));
assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD));
}
@Test
public void testClassificationConstantsAreUnique() {
Set<Integer> values = new LinkedHashSet<>();
values.add(MotionEvent.CLASSIFICATION_NONE);
values.add(MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE);
values.add(MotionEvent.CLASSIFICATION_DEEP_PRESS);
assertEquals(3, values.size());
}
/**
* The motion events 1 and 2 were created using one of the obtain methods.
* As a result, they should not have any classification.
* Only events generated by the framework are allowed to have classification other than NONE.
*/
@Test
public void testGetClassification() {
assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent1.getClassification());
assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent2.getClassification());
}
@Test
public void testNativeConverter() {
final MotionEvent event = MotionEvent.obtain(mDownTime, mEventTime,
MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, META_STATE);
event.setActionButton(MotionEvent.BUTTON_PRIMARY);
nativeMotionEventTest(event);
}
}