1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.cts; 18 19 import static android.view.cts.MotionEventUtils.withCoords; 20 import static android.view.cts.MotionEventUtils.withProperties; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertTrue; 26 import static org.junit.Assert.fail; 27 28 import android.graphics.Matrix; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.os.SystemClock; 32 import android.text.TextUtils; 33 import android.view.InputDevice; 34 import android.view.KeyEvent; 35 import android.view.MotionEvent; 36 import android.view.MotionEvent.PointerCoords; 37 import android.view.MotionEvent.PointerProperties; 38 import android.view.cts.MotionEventUtils.PointerCoordsBuilder; 39 import android.view.cts.MotionEventUtils.PointerPropertiesBuilder; 40 41 import androidx.test.filters.SmallTest; 42 import androidx.test.runner.AndroidJUnit4; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 49 import java.util.LinkedHashSet; 50 import java.util.Set; 51 52 /** 53 * Test {@link MotionEvent}. 54 */ 55 @SmallTest 56 @RunWith(AndroidJUnit4.class) 57 public class MotionEventTest { 58 private MotionEvent mMotionEvent1; 59 private MotionEvent mMotionEvent2; 60 private MotionEvent mMotionEventDynamic; 61 private long mDownTime; 62 private long mEventTime; 63 private static final float X_3F = 3.0f; 64 private static final float Y_4F = 4.0f; 65 private static final int META_STATE = KeyEvent.META_SHIFT_ON; 66 private static final float PRESSURE_1F = 1.0f; 67 private static final float SIZE_1F = 1.0f; 68 private static final float X_PRECISION_3F = 3.0f; 69 private static final float Y_PRECISION_4F = 4.0f; 70 private static final int DEVICE_ID_1 = 1; 71 private static final int EDGE_FLAGS = MotionEvent.EDGE_TOP; 72 private static final float DELTA = 0.01f; 73 private static final float RAW_COORD_TOLERANCE = 0.001f; 74 75 @Before setup()76 public void setup() { 77 mDownTime = SystemClock.uptimeMillis(); 78 mEventTime = SystemClock.uptimeMillis(); 79 mMotionEvent1 = MotionEvent.obtain(mDownTime, mEventTime, 80 MotionEvent.ACTION_MOVE, X_3F, Y_4F, META_STATE); 81 mMotionEvent2 = MotionEvent.obtain(mDownTime, mEventTime, 82 MotionEvent.ACTION_MOVE, X_3F, Y_4F, PRESSURE_1F, SIZE_1F, META_STATE, 83 X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS); 84 } 85 86 @After teardown()87 public void teardown() { 88 if (null != mMotionEvent1) { 89 mMotionEvent1.recycle(); 90 } 91 if (null != mMotionEvent2) { 92 mMotionEvent2.recycle(); 93 } 94 if (null != mMotionEventDynamic) { 95 mMotionEventDynamic.recycle(); 96 } 97 } 98 99 @Test testObtainBasic()100 public void testObtainBasic() { 101 mMotionEvent1 = MotionEvent.obtain(mDownTime, mEventTime, 102 MotionEvent.ACTION_DOWN, X_3F, Y_4F, META_STATE); 103 assertNotNull(mMotionEvent1); 104 assertEquals(mDownTime, mMotionEvent1.getDownTime()); 105 assertEquals(mEventTime, mMotionEvent1.getEventTime()); 106 assertEquals(MotionEvent.ACTION_DOWN, mMotionEvent1.getAction()); 107 assertEquals(X_3F, mMotionEvent1.getX(), DELTA); 108 assertEquals(Y_4F, mMotionEvent1.getY(), DELTA); 109 assertEquals(X_3F, mMotionEvent1.getRawX(), DELTA); 110 assertEquals(Y_4F, mMotionEvent1.getRawY(), DELTA); 111 assertEquals(META_STATE, mMotionEvent1.getMetaState()); 112 assertEquals(0, mMotionEvent1.getDeviceId()); 113 assertEquals(0, mMotionEvent1.getEdgeFlags()); 114 assertEquals(PRESSURE_1F, mMotionEvent1.getPressure(), DELTA); 115 assertEquals(SIZE_1F, mMotionEvent1.getSize(), DELTA); 116 assertEquals(1.0f, mMotionEvent1.getXPrecision(), DELTA); 117 assertEquals(1.0f, mMotionEvent1.getYPrecision(), DELTA); 118 } 119 120 @Test testObtainFromMotionEvent()121 public void testObtainFromMotionEvent() { 122 mMotionEventDynamic = MotionEvent.obtain(mMotionEvent2); 123 assertNotNull(mMotionEventDynamic); 124 assertEquals(mMotionEvent2.getDownTime(), mMotionEventDynamic.getDownTime()); 125 assertEquals(mMotionEvent2.getEventTime(), mMotionEventDynamic.getEventTime()); 126 assertEquals(mMotionEvent2.getAction(), mMotionEventDynamic.getAction()); 127 assertEquals(mMotionEvent2.getX(), mMotionEventDynamic.getX(), DELTA); 128 assertEquals(mMotionEvent2.getY(), mMotionEventDynamic.getY(), DELTA); 129 assertEquals(mMotionEvent2.getX(), mMotionEventDynamic.getRawX(), DELTA); 130 assertEquals(mMotionEvent2.getY(), mMotionEventDynamic.getRawY(), DELTA); 131 assertEquals(mMotionEvent2.getMetaState(), mMotionEventDynamic.getMetaState()); 132 assertEquals(mMotionEvent2.getDeviceId(), mMotionEventDynamic.getDeviceId()); 133 assertEquals(mMotionEvent2.getEdgeFlags(), mMotionEventDynamic.getEdgeFlags()); 134 assertEquals(mMotionEvent2.getPressure(), mMotionEventDynamic.getPressure(), DELTA); 135 assertEquals(mMotionEvent2.getSize(), mMotionEventDynamic.getSize(), DELTA); 136 assertEquals(mMotionEvent2.getXPrecision(), mMotionEventDynamic.getXPrecision(), DELTA); 137 assertEquals(mMotionEvent2.getYPrecision(), mMotionEventDynamic.getYPrecision(), DELTA); 138 } 139 140 @Test testObtainAllFields()141 public void testObtainAllFields() { 142 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 143 MotionEvent.ACTION_DOWN, X_3F, Y_4F, PRESSURE_1F, SIZE_1F, META_STATE, 144 X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS); 145 assertNotNull(mMotionEventDynamic); 146 assertEquals(mDownTime, mMotionEventDynamic.getDownTime()); 147 assertEquals(mEventTime, mMotionEventDynamic.getEventTime()); 148 assertEquals(MotionEvent.ACTION_DOWN, mMotionEventDynamic.getAction()); 149 assertEquals(X_3F, mMotionEventDynamic.getX(), DELTA); 150 assertEquals(Y_4F, mMotionEventDynamic.getY(), DELTA); 151 assertEquals(X_3F, mMotionEventDynamic.getRawX(), DELTA); 152 assertEquals(Y_4F, mMotionEventDynamic.getRawY(), DELTA); 153 assertEquals(META_STATE, mMotionEventDynamic.getMetaState()); 154 assertEquals(DEVICE_ID_1, mMotionEventDynamic.getDeviceId()); 155 assertEquals(EDGE_FLAGS, mMotionEventDynamic.getEdgeFlags()); 156 assertEquals(PRESSURE_1F, mMotionEventDynamic.getPressure(), DELTA); 157 assertEquals(SIZE_1F, mMotionEventDynamic.getSize(), DELTA); 158 assertEquals(X_PRECISION_3F, mMotionEventDynamic.getXPrecision(), DELTA); 159 assertEquals(Y_PRECISION_4F, mMotionEventDynamic.getYPrecision(), DELTA); 160 } 161 162 @Test testObtainFromPropertyArrays()163 public void testObtainFromPropertyArrays() { 164 PointerCoordsBuilder coordsBuilder0 = 165 withCoords(X_3F, Y_4F).withPressure(PRESSURE_1F).withSize(SIZE_1F). 166 withTool(1.2f, 1.4f); 167 PointerCoordsBuilder coordsBuilder1 = 168 withCoords(X_3F + 1.0f, Y_4F - 2.0f).withPressure(PRESSURE_1F + 0.2f). 169 withSize(SIZE_1F + 0.5f).withTouch(2.2f, 0.6f); 170 171 PointerPropertiesBuilder propertiesBuilder0 = 172 withProperties(0, MotionEvent.TOOL_TYPE_FINGER); 173 PointerPropertiesBuilder propertiesBuilder1 = 174 withProperties(1, MotionEvent.TOOL_TYPE_FINGER); 175 176 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 177 MotionEvent.ACTION_MOVE, 2, 178 new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() }, 179 new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() }, 180 META_STATE, 0, X_PRECISION_3F, Y_PRECISION_4F, DEVICE_ID_1, EDGE_FLAGS, 181 InputDevice.SOURCE_TOUCHSCREEN, 0); 182 183 // We expect to have data for two pointers 184 assertEquals(2, mMotionEventDynamic.getPointerCount()); 185 assertEquals(0, mMotionEventDynamic.getPointerId(0)); 186 assertEquals(1, mMotionEventDynamic.getPointerId(1)); 187 assertEquals(0, mMotionEventDynamic.getFlags()); 188 verifyCurrentPointerData(mMotionEventDynamic, 189 new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 }, 190 new PointerCoordsBuilder[] { coordsBuilder0, coordsBuilder1 }); 191 } 192 193 @Test testObtainNoHistory()194 public void testObtainNoHistory() { 195 // Add two batch to one of our events 196 mMotionEvent2.addBatch(mEventTime + 10, X_3F + 5.0f, Y_4F + 5.0f, 0.5f, 0.5f, 0); 197 mMotionEvent2.addBatch(mEventTime + 20, X_3F + 10.0f, Y_4F + 15.0f, 2.0f, 3.0f, 0); 198 // The newly added batch should be the "new" values of the event 199 withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f). 200 verifyMatches(mMotionEvent2); 201 assertEquals(mEventTime + 20, mMotionEvent2.getEventTime()); 202 // We should have history with 2 entries 203 assertEquals(2, mMotionEvent2.getHistorySize()); 204 // The previous data should be history at index 1 205 withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f). 206 verifyMatchesHistorical(mMotionEvent2, 1); 207 assertEquals(mEventTime + 10, mMotionEvent2.getHistoricalEventTime(1)); 208 // And the original data should be history at index 0 209 withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f). 210 verifyMatchesHistorical(mMotionEvent2, 0); 211 assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0)); 212 213 assertEquals(2, mMotionEvent2.getHistorySize()); 214 215 mMotionEventDynamic = MotionEvent.obtainNoHistory(mMotionEvent2); 216 // The newly obtained event should have the matching current content 217 withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f). 218 verifyMatches(mMotionEvent2); 219 // And no history 220 assertEquals(0, mMotionEventDynamic.getHistorySize()); 221 } 222 223 @Test testAccessAction()224 public void testAccessAction() { 225 assertEquals(MotionEvent.ACTION_MOVE, mMotionEvent1.getAction()); 226 227 mMotionEvent1.setAction(MotionEvent.ACTION_UP); 228 assertEquals(MotionEvent.ACTION_UP, mMotionEvent1.getAction()); 229 230 mMotionEvent1.setAction(MotionEvent.ACTION_MOVE); 231 assertEquals(MotionEvent.ACTION_MOVE, mMotionEvent1.getAction()); 232 233 mMotionEvent1.setAction(MotionEvent.ACTION_CANCEL); 234 assertEquals(MotionEvent.ACTION_CANCEL, mMotionEvent1.getAction()); 235 236 mMotionEvent1.setAction(MotionEvent.ACTION_DOWN); 237 assertEquals(MotionEvent.ACTION_DOWN, mMotionEvent1.getAction()); 238 } 239 240 @Test testDescribeContents()241 public void testDescribeContents() { 242 // make sure this method never throw any exception. 243 mMotionEvent2.describeContents(); 244 } 245 246 @Test testAccessEdgeFlags()247 public void testAccessEdgeFlags() { 248 assertEquals(EDGE_FLAGS, mMotionEvent2.getEdgeFlags()); 249 250 int edgeFlags = 10; 251 mMotionEvent2.setEdgeFlags(edgeFlags); 252 assertEquals(edgeFlags, mMotionEvent2.getEdgeFlags()); 253 } 254 255 @Test testWriteToParcel()256 public void testWriteToParcel() { 257 Parcel parcel = Parcel.obtain(); 258 mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 259 parcel.setDataPosition(0); 260 261 MotionEvent motionEvent = MotionEvent.CREATOR.createFromParcel(parcel); 262 assertEquals(mMotionEvent2.getRawY(), motionEvent.getRawY(), DELTA); 263 assertEquals(mMotionEvent2.getRawX(), motionEvent.getRawX(), DELTA); 264 assertEquals(mMotionEvent2.getY(), motionEvent.getY(), DELTA); 265 assertEquals(mMotionEvent2.getX(), motionEvent.getX(), DELTA); 266 assertEquals(mMotionEvent2.getAction(), motionEvent.getAction()); 267 assertEquals(mMotionEvent2.getDownTime(), motionEvent.getDownTime()); 268 assertEquals(mMotionEvent2.getEventTime(), motionEvent.getEventTime()); 269 assertEquals(mMotionEvent2.getEdgeFlags(), motionEvent.getEdgeFlags()); 270 assertEquals(mMotionEvent2.getDeviceId(), motionEvent.getDeviceId()); 271 } 272 273 @Test testReadFromParcelWithInvalidPointerCountSize()274 public void testReadFromParcelWithInvalidPointerCountSize() { 275 Parcel parcel = Parcel.obtain(); 276 mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 277 278 // Move to pointer id count. 279 parcel.setDataPosition(4); 280 parcel.writeInt(17); 281 282 parcel.setDataPosition(0); 283 try { 284 MotionEvent.CREATOR.createFromParcel(parcel); 285 fail("deserialized invalid parcel"); 286 } catch (RuntimeException e) { 287 // Expected. 288 } 289 } 290 291 @Test testReadFromParcelWithInvalidSampleSize()292 public void testReadFromParcelWithInvalidSampleSize() { 293 Parcel parcel = Parcel.obtain(); 294 mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 295 296 // Move to sample count. 297 parcel.setDataPosition(2 * 4); 298 parcel.writeInt(0x000f0000); 299 300 parcel.setDataPosition(0); 301 try { 302 MotionEvent.CREATOR.createFromParcel(parcel); 303 fail("deserialized invalid parcel"); 304 } catch (RuntimeException e) { 305 // Expected. 306 } 307 } 308 309 @Test testToString()310 public void testToString() { 311 // make sure this method never throw exception. 312 mMotionEvent2.toString(); 313 } 314 315 @Test testOffsetLocation()316 public void testOffsetLocation() { 317 assertEquals(X_3F, mMotionEvent2.getX(), DELTA); 318 assertEquals(Y_4F, mMotionEvent2.getY(), DELTA); 319 320 float offsetX = 1.0f; 321 float offsetY = 1.0f; 322 mMotionEvent2.offsetLocation(offsetX, offsetY); 323 withCoords(X_3F + offsetX, Y_4F + offsetY).withPressure(PRESSURE_1F).withSize(SIZE_1F). 324 verifyMatches(mMotionEvent2); 325 } 326 327 @Test testSetLocation()328 public void testSetLocation() { 329 assertEquals(X_3F, mMotionEvent2.getX(), DELTA); 330 assertEquals(Y_4F, mMotionEvent2.getY(), DELTA); 331 332 mMotionEvent2.setLocation(0.0f, 0.0f); 333 withCoords(0.0f, 0.0f).withPressure(PRESSURE_1F).withSize(SIZE_1F). 334 verifyMatches(mMotionEvent2); 335 336 mMotionEvent2.setLocation(2.0f, 2.0f); 337 withCoords(2.0f, 2.0f).withPressure(PRESSURE_1F).withSize(SIZE_1F). 338 verifyMatches(mMotionEvent2); 339 } 340 341 @Test testGetHistoricalData()342 public void testGetHistoricalData() { 343 assertEquals(0, mMotionEvent2.getHistorySize()); 344 345 mMotionEvent2.addBatch(mEventTime + 10, X_3F + 5.0f, Y_4F + 5.0f, 0.5f, 0.5f, 0); 346 // The newly added batch should be the "new" values of the event 347 withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f). 348 verifyMatches(mMotionEvent2); 349 assertEquals(mEventTime + 10, mMotionEvent2.getEventTime()); 350 // We should have history with 1 entry 351 assertEquals(1, mMotionEvent2.getHistorySize()); 352 // And the previous / original data should be history at index 0 353 assertEquals(1, mMotionEvent2.getHistorySize()); 354 withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f). 355 verifyMatchesHistorical(mMotionEvent2, 0); 356 assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0)); 357 358 // Add another update batch to our event 359 mMotionEvent2.addBatch(mEventTime + 20, X_3F + 10.0f, Y_4F + 15.0f, 2.0f, 3.0f, 0); 360 // The newly added batch should be the "new" values of the event 361 withCoords(X_3F + 10.0f, Y_4F + 15.0f).withPressure(2.0f).withSize(3.0f). 362 verifyMatches(mMotionEvent2); 363 assertEquals(mEventTime + 20, mMotionEvent2.getEventTime()); 364 // We should have history with 2 entries 365 assertEquals(2, mMotionEvent2.getHistorySize()); 366 // The previous data should be history at index 1 367 withCoords(X_3F + 5.0f, Y_4F + 5.0f).withPressure(0.5f).withSize(0.5f). 368 verifyMatchesHistorical(mMotionEvent2, 1); 369 assertEquals(mEventTime + 10, mMotionEvent2.getHistoricalEventTime(1)); 370 // And the original data should be history at index 0 371 withCoords(X_3F, Y_4F).withPressure(1.0f).withSize(1.0f). 372 verifyMatchesHistorical(mMotionEvent2, 0); 373 assertEquals(mEventTime, mMotionEvent2.getHistoricalEventTime(0)); 374 } 375 verifyCurrentPointerData(MotionEvent motionEvent, PointerPropertiesBuilder[] pointerPropertiesBuilders, PointerCoordsBuilder[] pointerCoordsBuilders)376 private static void verifyCurrentPointerData(MotionEvent motionEvent, 377 PointerPropertiesBuilder[] pointerPropertiesBuilders, 378 PointerCoordsBuilder[] pointerCoordsBuilders) { 379 assertNotNull(motionEvent); 380 assertNotNull(pointerPropertiesBuilders); 381 assertNotNull(pointerCoordsBuilders); 382 final int pointerCount = motionEvent.getPointerCount(); 383 assertEquals(pointerCount, pointerPropertiesBuilders.length); 384 assertEquals(pointerCount, pointerCoordsBuilders.length); 385 386 // Test that we have the expected data fetched via MotionEvent.getPointerCoords API 387 for (int i = 0; i < pointerCount; i++) { 388 pointerCoordsBuilders[i].verifyMatchesPointerCoords(motionEvent, i); 389 } 390 391 // Test that we have the expected data fetched via per-field MotionEvent getter APIs 392 for (int i = 0; i < pointerCount; i++) { 393 pointerCoordsBuilders[i].verifyMatches(motionEvent, i); 394 } 395 396 // Test that we have the expected data fetched via MotionEvent.getPointerProperties API 397 for (int i = 0; i < pointerCount; i++) { 398 pointerPropertiesBuilders[i].verifyMatchesPointerProperties(motionEvent, i); 399 } 400 401 // Test that we have the expected data fetched via per-field MotionEvent getter APIs 402 for (int i = 0; i < pointerCount; i++) { 403 pointerPropertiesBuilders[i].verifyMatches(motionEvent, i); 404 } 405 } 406 verifyHistoricalPointerData(MotionEvent motionEvent, PointerCoordsBuilder[] pointerCoordsBuilders, int pos)407 private static void verifyHistoricalPointerData(MotionEvent motionEvent, 408 PointerCoordsBuilder[] pointerCoordsBuilders, int pos) { 409 assertNotNull(motionEvent); 410 assertNotNull(pointerCoordsBuilders); 411 final int pointerCount = motionEvent.getPointerCount(); 412 assertEquals(pointerCount, pointerCoordsBuilders.length); 413 414 // Test that we have the expected data fetched via MotionEvent.getHistoricalPointerCoords 415 // API 416 for (int i = 0; i < pointerCount; i++) { 417 pointerCoordsBuilders[i].verifyMatchesHistoricalPointerCoords(motionEvent, i, pos); 418 } 419 420 // Test that we have the expected data fetched via per-field MotionEvent getter APIs 421 for (int i = 0; i < pointerCount; i++) { 422 pointerCoordsBuilders[i].verifyMatchesHistorical(motionEvent, i, pos); 423 } 424 } 425 426 @Test testGetCurrentDataWithTwoPointers()427 public void testGetCurrentDataWithTwoPointers() { 428 PointerCoordsBuilder coordsBuilder0 = 429 withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f, 1.4f); 430 PointerCoordsBuilder coordsBuilder1 = 431 withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTouch(2.2f, 0.6f); 432 433 PointerPropertiesBuilder propertiesBuilder0 = 434 withProperties(0, MotionEvent.TOOL_TYPE_FINGER); 435 PointerPropertiesBuilder propertiesBuilder1 = 436 withProperties(1, MotionEvent.TOOL_TYPE_FINGER); 437 438 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 439 MotionEvent.ACTION_MOVE, 2, 440 new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() }, 441 new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() }, 442 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); 443 444 // We expect to have data for two pointers 445 assertEquals(2, mMotionEventDynamic.getPointerCount()); 446 assertEquals(0, mMotionEventDynamic.getPointerId(0)); 447 assertEquals(1, mMotionEventDynamic.getPointerId(1)); 448 assertEquals(0, mMotionEventDynamic.getFlags()); 449 verifyCurrentPointerData(mMotionEventDynamic, 450 new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 }, 451 new PointerCoordsBuilder[] { coordsBuilder0, coordsBuilder1 }); 452 } 453 454 /** 455 * Verify we can get raw coordinates for specific pointers using MotionEvent#getRawX(int) and 456 * MotionEvent#getRawY(int). Also verity MotionEvent#getRawX() and MotionEvent#getRawY() 457 * returns the raw coordinates of pointer with pointer index 0. 458 */ 459 @Test testGetRawCoordsWithTwoPointers()460 public void testGetRawCoordsWithTwoPointers() { 461 PointerCoordsBuilder coordsBuilder0 = 462 withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f, 1.4f); 463 PointerCoordsBuilder coordsBuilder1 = 464 withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTouch(2.2f, 0.6f); 465 466 PointerPropertiesBuilder propertiesBuilder0 = 467 withProperties(0, MotionEvent.TOOL_TYPE_FINGER); 468 PointerPropertiesBuilder propertiesBuilder1 = 469 withProperties(1, MotionEvent.TOOL_TYPE_FINGER); 470 471 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 472 MotionEvent.ACTION_MOVE, 2, 473 new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() }, 474 new PointerCoords[] { coordsBuilder0.build(), coordsBuilder1.build() }, 475 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); 476 477 assertEquals(10.0f, mMotionEventDynamic.getRawX(), RAW_COORD_TOLERANCE); 478 assertEquals(20.0f, mMotionEventDynamic.getRawY(), RAW_COORD_TOLERANCE); 479 480 // Assert that getRawX returns the results for the first pointer index. 481 assertEquals(mMotionEventDynamic.getRawX(), mMotionEventDynamic.getRawX(0), 482 RAW_COORD_TOLERANCE); 483 assertEquals(mMotionEventDynamic.getRawY(), mMotionEventDynamic.getRawY(0), 484 RAW_COORD_TOLERANCE); 485 486 assertEquals(30.0f, mMotionEventDynamic.getRawX(1), RAW_COORD_TOLERANCE); 487 assertEquals(40.0f, mMotionEventDynamic.getRawY(1), RAW_COORD_TOLERANCE); 488 } 489 490 491 @Test testGetHistoricalDataWithTwoPointers()492 public void testGetHistoricalDataWithTwoPointers() { 493 // PHASE 1 - construct the initial data for the event 494 PointerCoordsBuilder coordsBuilderInitial0 = 495 withCoords(10.0f, 20.0f).withPressure(1.2f).withSize(2.0f).withTool(1.2f, 1.4f). 496 withTouch(0.7f, 0.6f).withOrientation(2.0f); 497 PointerCoordsBuilder coordsBuilderInitial1 = 498 withCoords(30.0f, 40.0f).withPressure(1.4f).withSize(3.0f).withTool(1.3f, 1.7f). 499 withTouch(2.7f, 3.6f).withOrientation(1.0f); 500 501 PointerPropertiesBuilder propertiesBuilder0 = 502 withProperties(0, MotionEvent.TOOL_TYPE_FINGER); 503 PointerPropertiesBuilder propertiesBuilder1 = 504 withProperties(1, MotionEvent.TOOL_TYPE_FINGER); 505 506 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 507 MotionEvent.ACTION_MOVE, 2, 508 new PointerProperties[] { propertiesBuilder0.build(), propertiesBuilder1.build() }, 509 new PointerCoords[] { 510 coordsBuilderInitial0.build(), coordsBuilderInitial1.build() }, 511 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); 512 513 // We expect to have data for two pointers 514 assertEquals(2, mMotionEventDynamic.getPointerCount()); 515 assertEquals(0, mMotionEventDynamic.getPointerId(0)); 516 assertEquals(1, mMotionEventDynamic.getPointerId(1)); 517 assertEquals(0, mMotionEventDynamic.getFlags()); 518 verifyCurrentPointerData(mMotionEventDynamic, 519 new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 }, 520 new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 }); 521 522 // PHASE 2 - add a new batch of data to our event 523 PointerCoordsBuilder coordsBuilderNext0 = 524 withCoords(15.0f, 25.0f).withPressure(1.6f).withSize(2.2f).withTool(1.2f, 1.4f). 525 withTouch(1.0f, 0.9f).withOrientation(2.2f); 526 PointerCoordsBuilder coordsBuilderNext1 = 527 withCoords(35.0f, 45.0f).withPressure(1.8f).withSize(3.2f).withTool(1.2f, 1.4f). 528 withTouch(0.7f, 0.6f).withOrientation(2.9f); 529 530 mMotionEventDynamic.addBatch(mEventTime + 10, 531 new PointerCoords[] { coordsBuilderNext0.build(), coordsBuilderNext1.build() }, 0); 532 // We still expect to have data for two pointers 533 assertEquals(2, mMotionEventDynamic.getPointerCount()); 534 assertEquals(0, mMotionEventDynamic.getPointerId(0)); 535 assertEquals(1, mMotionEventDynamic.getPointerId(1)); 536 assertEquals(0, mMotionEventDynamic.getFlags()); 537 538 // The newly added batch should be the "new" values of the event 539 verifyCurrentPointerData(mMotionEventDynamic, 540 new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 }, 541 new PointerCoordsBuilder[] { coordsBuilderNext0, coordsBuilderNext1 }); 542 assertEquals(mEventTime + 10, mMotionEventDynamic.getEventTime()); 543 // We should have history with 1 entry 544 assertEquals(1, mMotionEventDynamic.getHistorySize()); 545 // And the previous / original data should be history at index 0 546 assertEquals(1, mMotionEventDynamic.getHistorySize()); 547 verifyHistoricalPointerData(mMotionEventDynamic, 548 new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 }, 549 0); 550 551 // PHASE 3 - add one more new batch of data to our event 552 PointerCoordsBuilder coordsBuilderLast0 = 553 withCoords(18.0f, 28.0f).withPressure(1.1f).withSize(2.9f).withTool(1.5f, 1.9f). 554 withTouch(1.2f, 5.0f).withOrientation(3.2f); 555 PointerCoordsBuilder coordsBuilderLast1 = 556 withCoords(38.0f, 48.0f).withPressure(1.2f).withSize(2.5f).withTool(0.2f, 0.4f). 557 withTouch(2.7f, 4.6f).withOrientation(0.2f); 558 559 mMotionEventDynamic.addBatch(mEventTime + 20, 560 new PointerCoords[] { coordsBuilderLast0.build(), coordsBuilderLast1.build() }, 0); 561 // We still expect to have data for two pointers 562 assertEquals(2, mMotionEventDynamic.getPointerCount()); 563 assertEquals(0, mMotionEventDynamic.getPointerId(0)); 564 assertEquals(1, mMotionEventDynamic.getPointerId(1)); 565 assertEquals(0, mMotionEventDynamic.getFlags()); 566 567 // The newly added batch should be the "new" values of the event 568 verifyCurrentPointerData(mMotionEventDynamic, 569 new PointerPropertiesBuilder[] { propertiesBuilder0, propertiesBuilder1 }, 570 new PointerCoordsBuilder[] { coordsBuilderLast0, coordsBuilderLast1 }); 571 assertEquals(mEventTime + 20, mMotionEventDynamic.getEventTime()); 572 // We should have history with 2 entries 573 assertEquals(2, mMotionEventDynamic.getHistorySize()); 574 // The previous data should be history at index 1 575 verifyHistoricalPointerData(mMotionEventDynamic, 576 new PointerCoordsBuilder[] { coordsBuilderNext0, coordsBuilderNext1 }, 577 1); 578 assertEquals(mEventTime + 10, mMotionEventDynamic.getHistoricalEventTime(1)); 579 // And the original data should be history at index 0 580 verifyHistoricalPointerData(mMotionEventDynamic, 581 new PointerCoordsBuilder[] { coordsBuilderInitial0, coordsBuilderInitial1 }, 582 0); 583 assertEquals(mEventTime, mMotionEventDynamic.getHistoricalEventTime(0)); 584 } 585 586 @Test testGetHistorySize()587 public void testGetHistorySize() { 588 long eventTime = SystemClock.uptimeMillis(); 589 float x = 10.0f; 590 float y = 20.0f; 591 float pressure = 1.0f; 592 float size = 1.0f; 593 594 mMotionEvent2.setAction(MotionEvent.ACTION_DOWN); 595 assertEquals(0, mMotionEvent2.getHistorySize()); 596 597 mMotionEvent2.setAction(MotionEvent.ACTION_MOVE); 598 mMotionEvent2.addBatch(eventTime, x, y, pressure, size, 0); 599 assertEquals(1, mMotionEvent2.getHistorySize()); 600 } 601 602 @Test testRecycle()603 public void testRecycle() { 604 mMotionEvent2.setAction(MotionEvent.ACTION_MOVE); 605 assertEquals(0, mMotionEvent2.getHistorySize()); 606 mMotionEvent2.addBatch(mEventTime, 10.0f, 5.0f, 1.0f, 0.0f, 0); 607 assertEquals(1, mMotionEvent2.getHistorySize()); 608 609 mMotionEvent2.recycle(); 610 611 try { 612 mMotionEvent2.recycle(); 613 fail("recycle() should throw an exception when the event has already been recycled."); 614 } catch (RuntimeException ex) { 615 } 616 617 mMotionEvent2 = null; // since it was recycled, don't try to recycle again in tear down 618 } 619 620 @Test(expected=IllegalArgumentException.class) testTransformShouldThrowWhenMatrixIsNull()621 public void testTransformShouldThrowWhenMatrixIsNull() { 622 // transform() should throw an exception when matrix is null 623 mMotionEvent1.transform(null); 624 } 625 626 @Test testTransformShouldApplyMatrixToPointsAndPreserveRawPosition()627 public void testTransformShouldApplyMatrixToPointsAndPreserveRawPosition() { 628 // Generate some points on a circle, then assign each point to a pointer. 629 // The location of pointer 'i' is a point on a circle of radius ROTATION centered at (3,2) 630 // at an angle of ARC * i degrees clockwise relative to the Y axis. 631 // The geometrical representation is irrelevant to the test, it's just easy to generate 632 // and check rotation. We set the orientation to the same angle. 633 // Coordinate system: down is increasing Y, right is increasing X. 634 final float PI_180 = (float) (Math.PI / 180); 635 final float RADIUS = 10; 636 final float ARC = 36; 637 final float ROTATION = ARC * 2; 638 639 final int pointerCount = 11; 640 final int[] pointerIds = new int[pointerCount]; 641 final PointerCoords[] pointerCoords = new PointerCoords[pointerCount]; 642 final PointerCoords[] originalRawCoords = new PointerCoords[pointerCount]; 643 for (int i = 0; i < pointerCount; i++) { 644 final PointerCoords c = new PointerCoords(); 645 final float angle = (float) (i * ARC * PI_180); 646 pointerIds[i] = i; 647 pointerCoords[i] = c; 648 c.x = (float) (Math.sin(angle) * RADIUS + 3); 649 c.y = (float) (- Math.cos(angle) * RADIUS + 2); 650 c.orientation = angle; 651 originalRawCoords[i] = new PointerCoords(c); 652 } 653 final MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 654 pointerCount, pointerIds, pointerCoords, 0, 0, 0, 0, 0, 0, 0); 655 dump("Original points.", event); 656 657 // Check original raw X and Y assumption. 658 for (int i = 0; i < pointerCount; i++) { 659 assertEquals(originalRawCoords[i].x, event.getRawX(i), RAW_COORD_TOLERANCE); 660 assertEquals(originalRawCoords[i].y, event.getRawY(i), RAW_COORD_TOLERANCE); 661 } 662 663 // Now translate the motion event so the circle's origin is at (0,0). 664 event.offsetLocation(-3, -2); 665 dump("Translated points.", event); 666 667 // Offsetting the location should preserve the raw X and Y of all pointers. 668 for (int i = 0; i < pointerCount; i++) { 669 assertEquals(originalRawCoords[i].x, event.getRawX(i), RAW_COORD_TOLERANCE); 670 assertEquals(originalRawCoords[i].y, event.getRawY(i), RAW_COORD_TOLERANCE); 671 } 672 673 // Apply a rotation about the origin by ROTATION degrees clockwise. 674 Matrix matrix = new Matrix(); 675 matrix.setRotate(ROTATION); 676 event.transform(matrix); 677 dump("Rotated points.", event); 678 679 // Check the points. 680 for (int i = 0; i < pointerCount; i++) { 681 final PointerCoords c = pointerCoords[i]; 682 event.getPointerCoords(i, c); 683 684 final float angle = (float) ((i * ARC + ROTATION) * PI_180); 685 assertEquals(Math.sin(angle) * RADIUS, c.x, RAW_COORD_TOLERANCE); 686 assertEquals(-Math.cos(angle) * RADIUS, c.y, RAW_COORD_TOLERANCE); 687 assertEquals(Math.tan(angle), Math.tan(c.orientation), 0.1); 688 } 689 690 // Applying the transformation should preserve the raw X and Y of the first pointer. 691 assertEquals(originalRawCoords[0].x, event.getRawX(), RAW_COORD_TOLERANCE); 692 assertEquals(originalRawCoords[0].y, event.getRawY(), RAW_COORD_TOLERANCE); 693 694 // TODO(b/124116082) Verify whether transformations on MotionEvents should preserve raw X 695 // and Y for all pointers. 696 } 697 dump(String label, MotionEvent ev)698 private void dump(String label, MotionEvent ev) { 699 if (false) { 700 StringBuilder msg = new StringBuilder(); 701 msg.append(label).append("\n"); 702 703 msg.append(" Raw: (").append(ev.getRawX()).append(",").append(ev.getRawY()).append(")\n"); 704 int pointerCount = ev.getPointerCount(); 705 for (int i = 0; i < pointerCount; i++) { 706 msg.append(" Pointer[").append(i).append("]: (") 707 .append(ev.getX(i)).append(",").append(ev.getY(i)).append("), orientation=") 708 .append(ev.getOrientation(i) * 180 / Math.PI).append(" deg\n"); 709 } 710 711 android.util.Log.i("TEST", msg.toString()); 712 } 713 } 714 715 @Test testPointerCoordsDefaultConstructor()716 public void testPointerCoordsDefaultConstructor() { 717 PointerCoords coords = new PointerCoords(); 718 719 assertEquals(0f, coords.x, 0.0f); 720 assertEquals(0f, coords.y, 0.0f); 721 assertEquals(0f, coords.pressure, 0.0f); 722 assertEquals(0f, coords.size, 0.0f); 723 assertEquals(0f, coords.touchMajor, 0.0f); 724 assertEquals(0f, coords.touchMinor, 0.0f); 725 assertEquals(0f, coords.toolMajor, 0.0f); 726 assertEquals(0f, coords.toolMinor, 0.0f); 727 assertEquals(0f, coords.orientation, 0.0f); 728 } 729 730 @Test testPointerCoordsCopyConstructor()731 public void testPointerCoordsCopyConstructor() { 732 PointerCoords coords = new PointerCoords(); 733 coords.x = 1; 734 coords.y = 2; 735 coords.pressure = 3; 736 coords.size = 4; 737 coords.touchMajor = 5; 738 coords.touchMinor = 6; 739 coords.toolMajor = 7; 740 coords.toolMinor = 8; 741 coords.orientation = 9; 742 coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10); 743 744 PointerCoords copy = new PointerCoords(coords); 745 assertEquals(1f, copy.x, 0.0f); 746 assertEquals(2f, copy.y, 0.0f); 747 assertEquals(3f, copy.pressure, 0.0f); 748 assertEquals(4f, copy.size, 0.0f); 749 assertEquals(5f, copy.touchMajor, 0.0f); 750 assertEquals(6f, copy.touchMinor, 0.0f); 751 assertEquals(7f, copy.toolMajor, 0.0f); 752 assertEquals(8f, copy.toolMinor, 0.0f); 753 assertEquals(9f, copy.orientation, 0.0f); 754 assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1), 0.0f); 755 } 756 757 @Test testPointerCoordsCopyFrom()758 public void testPointerCoordsCopyFrom() { 759 PointerCoords coords = new PointerCoords(); 760 coords.x = 1; 761 coords.y = 2; 762 coords.pressure = 3; 763 coords.size = 4; 764 coords.touchMajor = 5; 765 coords.touchMinor = 6; 766 coords.toolMajor = 7; 767 coords.toolMinor = 8; 768 coords.orientation = 9; 769 coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10); 770 771 PointerCoords copy = new PointerCoords(); 772 copy.copyFrom(coords); 773 assertEquals(1f, copy.x, 0.0f); 774 assertEquals(2f, copy.y, 0.0f); 775 assertEquals(3f, copy.pressure, 0.0f); 776 assertEquals(4f, copy.size, 0.0f); 777 assertEquals(5f, copy.touchMajor, 0.0f); 778 assertEquals(6f, copy.touchMinor, 0.0f); 779 assertEquals(7f, copy.toolMajor, 0.0f); 780 assertEquals(8f, copy.toolMinor, 0.0f); 781 assertEquals(9f, copy.orientation, 0.0f); 782 assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1), 0.0f); 783 } 784 785 @Test testPointerPropertiesDefaultConstructor()786 public void testPointerPropertiesDefaultConstructor() { 787 PointerProperties properties = new PointerProperties(); 788 789 assertEquals(MotionEvent.INVALID_POINTER_ID, properties.id); 790 assertEquals(MotionEvent.TOOL_TYPE_UNKNOWN, properties.toolType); 791 } 792 793 @Test testPointerPropertiesCopyConstructor()794 public void testPointerPropertiesCopyConstructor() { 795 PointerProperties properties = new PointerProperties(); 796 properties.id = 1; 797 properties.toolType = MotionEvent.TOOL_TYPE_MOUSE; 798 799 PointerProperties copy = new PointerProperties(properties); 800 assertEquals(1, copy.id); 801 assertEquals(MotionEvent.TOOL_TYPE_MOUSE, copy.toolType); 802 } 803 804 @Test testPointerPropertiesCopyFrom()805 public void testPointerPropertiesCopyFrom() { 806 PointerProperties properties = new PointerProperties(); 807 properties.id = 1; 808 properties.toolType = MotionEvent.TOOL_TYPE_MOUSE; 809 810 PointerProperties copy = new PointerProperties(); 811 copy.copyFrom(properties); 812 assertEquals(1, copy.id); 813 assertEquals(MotionEvent.TOOL_TYPE_MOUSE, copy.toolType); 814 } 815 816 @Test testActionToString()817 public void testActionToString() { 818 final int[] actions = { 819 MotionEvent.ACTION_DOWN, 820 MotionEvent.ACTION_UP, 821 MotionEvent.ACTION_MOVE, 822 MotionEvent.ACTION_CANCEL, 823 MotionEvent.ACTION_OUTSIDE, 824 MotionEvent.ACTION_HOVER_MOVE, 825 MotionEvent.ACTION_SCROLL, 826 MotionEvent.ACTION_HOVER_ENTER, 827 MotionEvent.ACTION_HOVER_EXIT, 828 MotionEvent.ACTION_BUTTON_PRESS, 829 MotionEvent.ACTION_BUTTON_RELEASE 830 }; 831 832 // There is no hard guarantee on the actual return result on any specific action 833 // from MotionEvent.actionToString. Verify that we are not crashing on those calls 834 // and that the return result on each is not empty 835 for (int i = 0; i < actions.length; i++) { 836 assertFalse(TextUtils.isEmpty(MotionEvent.actionToString(actions[i]))); 837 } 838 839 final int[] pointerActions = { 840 MotionEvent.ACTION_POINTER_UP, 841 MotionEvent.ACTION_POINTER_DOWN 842 }; 843 844 for (int i = 0; i < pointerActions.length; i++) { 845 for (int pointer = 0; pointer < 5; pointer++) { 846 int pointerAction = 847 pointerActions[i] | pointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT; 848 assertFalse(TextUtils.isEmpty(MotionEvent.actionToString(pointerAction))); 849 } 850 } 851 } 852 853 @Test testAxisFromToString()854 public void testAxisFromToString() { 855 final int[] axes = { 856 MotionEvent.AXIS_X, 857 MotionEvent.AXIS_Y, 858 MotionEvent.AXIS_PRESSURE, 859 MotionEvent.AXIS_SIZE, 860 MotionEvent.AXIS_TOUCH_MAJOR, 861 MotionEvent.AXIS_TOUCH_MINOR, 862 MotionEvent.AXIS_TOOL_MAJOR, 863 MotionEvent.AXIS_TOOL_MINOR, 864 MotionEvent.AXIS_ORIENTATION, 865 MotionEvent.AXIS_VSCROLL, 866 MotionEvent.AXIS_HSCROLL, 867 MotionEvent.AXIS_Z, 868 MotionEvent.AXIS_RX, 869 MotionEvent.AXIS_RY, 870 MotionEvent.AXIS_RZ, 871 MotionEvent.AXIS_HAT_X, 872 MotionEvent.AXIS_HAT_Y, 873 MotionEvent.AXIS_LTRIGGER, 874 MotionEvent.AXIS_RTRIGGER, 875 MotionEvent.AXIS_THROTTLE, 876 MotionEvent.AXIS_RUDDER, 877 MotionEvent.AXIS_WHEEL, 878 MotionEvent.AXIS_GAS, 879 MotionEvent.AXIS_BRAKE, 880 MotionEvent.AXIS_DISTANCE, 881 MotionEvent.AXIS_TILT, 882 MotionEvent.AXIS_SCROLL, 883 MotionEvent.AXIS_RELATIVE_X, 884 MotionEvent.AXIS_RELATIVE_Y, 885 MotionEvent.AXIS_GENERIC_1, 886 MotionEvent.AXIS_GENERIC_2, 887 MotionEvent.AXIS_GENERIC_3, 888 MotionEvent.AXIS_GENERIC_4, 889 MotionEvent.AXIS_GENERIC_5, 890 MotionEvent.AXIS_GENERIC_6, 891 MotionEvent.AXIS_GENERIC_7, 892 MotionEvent.AXIS_GENERIC_8, 893 MotionEvent.AXIS_GENERIC_9, 894 MotionEvent.AXIS_GENERIC_10, 895 MotionEvent.AXIS_GENERIC_11, 896 MotionEvent.AXIS_GENERIC_12, 897 MotionEvent.AXIS_GENERIC_13, 898 MotionEvent.AXIS_GENERIC_14, 899 MotionEvent.AXIS_GENERIC_15, 900 MotionEvent.AXIS_GENERIC_16 901 }; 902 903 // There is no hard guarantee on the actual return result on any specific axis 904 // from MotionEvent.axisToString. Verify that we are not crashing on those calls 905 // and that the return result on each is not empty. However, we do expect the two-way 906 // call chain of to/from to get us back to the original integer value. 907 for (int i = 0; i < axes.length; i++) { 908 String axisToString = MotionEvent.axisToString(axes[i]); 909 assertFalse(TextUtils.isEmpty(axisToString)); 910 assertEquals(axes[i], MotionEvent.axisFromString(axisToString)); 911 } 912 } 913 914 @Test testGetActionButton()915 public void testGetActionButton() { 916 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 917 MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0); 918 mMotionEventDynamic.setActionButton(MotionEvent.BUTTON_STYLUS_PRIMARY); 919 assertEquals(MotionEvent.BUTTON_STYLUS_PRIMARY, mMotionEventDynamic.getActionButton()); 920 mMotionEventDynamic.recycle(); 921 922 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 923 MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0); 924 mMotionEventDynamic.setActionButton(MotionEvent.BUTTON_SECONDARY); 925 assertEquals(MotionEvent.BUTTON_SECONDARY, mMotionEventDynamic.getActionButton()); 926 } 927 928 @Test testIsButtonPressed()929 public void testIsButtonPressed() { 930 mMotionEventDynamic = MotionEvent.obtain(mDownTime, mEventTime, 931 MotionEvent.ACTION_DOWN, X_3F, Y_4F, 0); 932 mMotionEventDynamic.setSource(InputDevice.SOURCE_MOUSE); 933 934 mMotionEventDynamic.setButtonState( 935 MotionEvent.BUTTON_PRIMARY | MotionEvent.BUTTON_STYLUS_PRIMARY); 936 assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY)); 937 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY)); 938 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); 939 assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY)); 940 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)); 941 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK)); 942 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD)); 943 944 mMotionEventDynamic.setButtonState(MotionEvent.BUTTON_PRIMARY); 945 assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY)); 946 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY)); 947 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); 948 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY)); 949 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)); 950 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK)); 951 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD)); 952 953 mMotionEventDynamic.setButtonState( 954 MotionEvent.BUTTON_FORWARD | MotionEvent.BUTTON_TERTIARY); 955 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_PRIMARY)); 956 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_SECONDARY)); 957 assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); 958 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY)); 959 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)); 960 assertFalse(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_BACK)); 961 assertTrue(mMotionEventDynamic.isButtonPressed(MotionEvent.BUTTON_FORWARD)); 962 } 963 964 @Test testClassificationConstantsAreUnique()965 public void testClassificationConstantsAreUnique() { 966 Set<Integer> values = new LinkedHashSet<>(); 967 values.add(MotionEvent.CLASSIFICATION_NONE); 968 values.add(MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE); 969 values.add(MotionEvent.CLASSIFICATION_DEEP_PRESS); 970 assertEquals(3, values.size()); 971 } 972 973 /** 974 * The motion events 1 and 2 were created using one of the obtain methods. 975 * As a result, they should not have any classification. 976 * Only events generated by the framework are allowed to have classification other than NONE. 977 */ 978 @Test testGetClassification()979 public void testGetClassification() { 980 assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent1.getClassification()); 981 assertEquals(MotionEvent.CLASSIFICATION_NONE, mMotionEvent2.getClassification()); 982 } 983 } 984