android.view.MotionEvent.PointerProperties Java Examples
The following examples show how to use
android.view.MotionEvent.PointerProperties.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 6 votes |
GenericTouchGesture(ContentViewCore contentViewCore, int startX0, int startY0, int deltaX0, int deltaY0, int startX1, int startY1, int deltaX1, int deltaY1) { mContentViewCore = contentViewCore; float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); int scaledTouchSlop = getScaledTouchSlop(); mPointers = new TouchPointer[2]; mPointers[0] = new TouchPointer(startX0, startY0, deltaX0, deltaY0, 0, scale, scaledTouchSlop); mPointers[1] = new TouchPointer(startX1, startY1, deltaX1, deltaY1, 1, scale, scaledTouchSlop); mPointerProperties = new PointerProperties[2]; mPointerProperties[0] = mPointers[0].getProperties(); mPointerProperties[1] = mPointers[1].getProperties(); mPointerCoords = new PointerCoords[2]; mPointerCoords[0] = mPointers[0].getCoords(); mPointerCoords[1] = mPointers[1].getCoords(); }
Example #2
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 6 votes |
GenericTouchGesture(ContentViewCore contentViewCore, int startX, int startY, int deltaX, int deltaY) { mContentViewCore = contentViewCore; float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); int scaledTouchSlop = getScaledTouchSlop(); mPointers = new TouchPointer[1]; mPointers[0] = new TouchPointer(startX, startY, deltaX, deltaY, 0, scale, scaledTouchSlop); mPointerProperties = new PointerProperties[1]; mPointerProperties[0] = mPointers[0].getProperties(); mPointerCoords = new PointerCoords[1]; mPointerCoords[0] = mPointers[0].getCoords(); }
Example #3
Source File: ComplexUiActionHandler.java From android-uiconductor with Apache License 2.0 | 6 votes |
/** Helper function to obtain a MotionEvent. */ private static MotionEvent getMotionEvent(long downTime, long eventTime, int action, float x, float y) { PointerProperties properties = new PointerProperties(); properties.id = 0; properties.toolType = Configurator.getInstance().getToolType(); PointerCoords coords = new PointerCoords(); coords.pressure = 1; coords.size = 1; coords.x = x; coords.y = y; return MotionEvent.obtain(downTime, eventTime, action, 1, new PointerProperties[] { properties }, new PointerCoords[] { coords }, 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); }
Example #4
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 6 votes |
GenericTouchGesture(ContentViewCore contentViewCore, int startX0, int startY0, int deltaX0, int deltaY0, int startX1, int startY1, int deltaX1, int deltaY1) { mContentViewCore = contentViewCore; float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); int scaledTouchSlop = getScaledTouchSlop(); mPointers = new TouchPointer[2]; mPointers[0] = new TouchPointer(startX0, startY0, deltaX0, deltaY0, 0, scale, scaledTouchSlop); mPointers[1] = new TouchPointer(startX1, startY1, deltaX1, deltaY1, 1, scale, scaledTouchSlop); mPointerProperties = new PointerProperties[2]; mPointerProperties[0] = mPointers[0].getProperties(); mPointerProperties[1] = mPointers[1].getProperties(); mPointerCoords = new PointerCoords[2]; mPointerCoords[0] = mPointers[0].getCoords(); mPointerCoords[1] = mPointers[1].getCoords(); }
Example #5
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 6 votes |
GenericTouchGesture(ContentViewCore contentViewCore, int startX, int startY, int deltaX, int deltaY) { mContentViewCore = contentViewCore; float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); int scaledTouchSlop = getScaledTouchSlop(); mPointers = new TouchPointer[1]; mPointers[0] = new TouchPointer(startX, startY, deltaX, deltaY, 0, scale, scaledTouchSlop); mPointerProperties = new PointerProperties[1]; mPointerProperties[0] = mPointers[0].getProperties(); mPointerCoords = new PointerCoords[1]; mPointerCoords[0] = mPointers[0].getCoords(); }
Example #6
Source File: MotionEventSynthesizer.java From 365browser with Apache License 2.0 | 6 votes |
@CalledByNative void setPointer(int index, int x, int y, int id) { assert (0 <= index && index < MAX_NUM_POINTERS); // Convert coordinates from density independent pixels to density dependent pixels. float scaleFactor = getDisplay().getDipScale(); PointerCoords coords = new PointerCoords(); coords.x = scaleFactor * x; coords.y = scaleFactor * y; coords.pressure = 1.0f; mPointerCoords[index] = coords; PointerProperties properties = new PointerProperties(); properties.id = id; mPointerProperties[index] = properties; }
Example #7
Source File: MotionEventBuilder.java From android-test with Apache License 2.0 | 6 votes |
/** Returns a MotionEvent with the provided data or reasonable defaults. */ public MotionEvent build() { if (pointerPropertiesList.size() == 0) { setPointer(0, 0); } if (actionIndex != -1) { action = action | (actionIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT); } return MotionEvent.obtain( downTime, eventTime, action, pointerPropertiesList.size(), pointerPropertiesList.toArray(new PointerProperties[pointerPropertiesList.size()]), pointerCoordsList.toArray(new MotionEvent.PointerCoords[pointerCoordsList.size()]), metaState, buttonState, xPrecision, yPrecision, deviceId, edgeFlags, source, flags); }
Example #8
Source File: GestureController.java From za-Farmer with MIT License | 5 votes |
/** Helper function to obtain a MotionEvent. */ private static MotionEvent getMotionEvent(long downTime, long eventTime, int action, List<PointerProperties> properties, List<PointerCoords> coordinates) { PointerProperties[] props = properties.toArray(new PointerProperties[properties.size()]); PointerCoords[] coords = coordinates.toArray(new PointerCoords[coordinates.size()]); return MotionEvent.obtain(downTime, eventTime, action, props.length, props, coords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); }
Example #9
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 5 votes |
TouchPointer(int startX, int startY, int deltaX, int deltaY, int id, float scale, int scaledTouchSlop) { mStartX = startX * scale; mStartY = startY * scale; float scaledDeltaX = deltaX * scale; float scaledDeltaY = deltaY * scale; if (scaledDeltaX != 0 || scaledDeltaY != 0) { // The touch handler only considers a pointer as moving once // it's been moved by more than scaledTouchSlop pixels. We // thus increase the delta distance so the move is actually // registered as covering the specified distance. float distance = (float)Math.sqrt(scaledDeltaX * scaledDeltaX + scaledDeltaY * scaledDeltaY); mDeltaX = scaledDeltaX * (1 + scaledTouchSlop / distance); mDeltaY = scaledDeltaY * (1 + scaledTouchSlop / distance); } else { mDeltaX = scaledDeltaX; mDeltaY = scaledDeltaY; } if (deltaX != 0 || deltaY != 0) { mStepX = mDeltaX / Math.abs(mDeltaX + mDeltaY); mStepY = mDeltaY / Math.abs(mDeltaX + mDeltaY); } else { mStepX = 0; mStepY = 0; } mProperties = new PointerProperties(); mProperties.id = id; mProperties.toolType = MotionEvent.TOOL_TYPE_FINGER; mCoords = new PointerCoords(); mCoords.x = mStartX; mCoords.y = mStartY; mCoords.pressure = 1.0f; }
Example #10
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 5 votes |
TouchPointer(int startX, int startY, int deltaX, int deltaY, int id, float scale, int scaledTouchSlop) { mStartX = startX * scale; mStartY = startY * scale; float scaledDeltaX = deltaX * scale; float scaledDeltaY = deltaY * scale; if (scaledDeltaX != 0 || scaledDeltaY != 0) { // The touch handler only considers a pointer as moving once // it's been moved by more than scaledTouchSlop pixels. We // thus increase the delta distance so the move is actually // registered as covering the specified distance. float distance = (float)Math.sqrt(scaledDeltaX * scaledDeltaX + scaledDeltaY * scaledDeltaY); mDeltaX = scaledDeltaX * (1 + scaledTouchSlop / distance); mDeltaY = scaledDeltaY * (1 + scaledTouchSlop / distance); } else { mDeltaX = scaledDeltaX; mDeltaY = scaledDeltaY; } if (deltaX != 0 || deltaY != 0) { mStepX = mDeltaX / Math.abs(mDeltaX + mDeltaY); mStepY = mDeltaY / Math.abs(mDeltaX + mDeltaY); } else { mStepX = 0; mStepY = 0; } mProperties = new PointerProperties(); mProperties.id = id; mProperties.toolType = MotionEvent.TOOL_TYPE_FINGER; mCoords = new PointerCoords(); mCoords.x = mStartX; mCoords.y = mStartY; mCoords.pressure = 1.0f; }
Example #11
Source File: MotionEventSubject.java From android-test with Apache License 2.0 | 5 votes |
public PointerPropertiesSubject pointerProperties(int pointerIndex) { PointerProperties outPointerProps = new PointerProperties(); actual.getPointerProperties(pointerIndex, outPointerProps); return check("getPointerProperties(%s)", pointerIndex) .about(PointerPropertiesSubject.pointerProperties()) .that(outPointerProps); }
Example #12
Source File: MotionEventBuilder.java From android-test with Apache License 2.0 | 5 votes |
/** * An expanded variant of {@link #setPointer(float, float)} that supports specifying all pointer * properties and coords data. */ public MotionEventBuilder setPointer( PointerProperties pointerProperties, PointerCoords pointerCoords) { pointerPropertiesList.add(pointerProperties); pointerCoordsList.add(pointerCoords); return this; }
Example #13
Source File: MotionEventBuilder.java From android-test with Apache License 2.0 | 5 votes |
/** * Simple mechanism to add a pointer to the MotionEvent. * * <p>Can be called multiple times to add multiple pointers to the event. */ public MotionEventBuilder setPointer(float x, float y) { PointerProperties pointerProperties = new PointerProperties(); pointerProperties.id = pointerPropertiesList.size(); PointerCoords pointerCoords = new PointerCoords(); pointerCoords.x = x; pointerCoords.y = y; return setPointer(pointerProperties, pointerCoords); }
Example #14
Source File: GestureController.java From JsDroidCmd with Mozilla Public License 2.0 | 5 votes |
public Pointer(int id, Point point) { prop = new PointerProperties(); prop.id = id; prop.toolType = MotionEvent.TOOL_TYPE_FINGER; coords = new PointerCoords(); coords.pressure = 1; coords.size = 1; coords.x = point.x; coords.y = point.y; }
Example #15
Source File: GestureController.java From JsDroidCmd with Mozilla Public License 2.0 | 5 votes |
/** Helper function to obtain a MotionEvent. */ private static MotionEvent getMotionEvent(long downTime, long eventTime, int action, List<PointerProperties> properties, List<PointerCoords> coordinates) { PointerProperties[] props = properties.toArray(new PointerProperties[properties.size()]); PointerCoords[] coords = coordinates.toArray(new PointerCoords[coordinates.size()]); return MotionEvent.obtain(downTime, eventTime, action, props.length, props, coords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); }
Example #16
Source File: GestureController.java From za-Farmer with MIT License | 5 votes |
public Pointer(int id, Point point) { prop = new PointerProperties(); prop.id = id; prop.toolType = MotionEvent.TOOL_TYPE_FINGER; coords = new PointerCoords(); coords.pressure = 1; coords.size = 1; coords.x = point.x; coords.y = point.y; }
Example #17
Source File: PointerPropertiesBuilder.java From android-test with Apache License 2.0 | 4 votes |
public PointerProperties build() { final PointerProperties pointerProperties = new PointerProperties(); pointerProperties.id = id; pointerProperties.toolType = toolType; return pointerProperties; }
Example #18
Source File: PointerPropertiesSubject.java From android-test with Apache License 2.0 | 4 votes |
public static PointerPropertiesSubject assertThat(PointerProperties other) { return Truth.assertAbout(pointerProperties()).that(other); }
Example #19
Source File: PointerPropertiesSubject.java From android-test with Apache License 2.0 | 4 votes |
public static Subject.Factory<PointerPropertiesSubject, PointerProperties> pointerProperties() { return PointerPropertiesSubject::new; }
Example #20
Source File: PointerPropertiesSubject.java From android-test with Apache License 2.0 | 4 votes |
private PointerPropertiesSubject( FailureMetadata failureMetadata, @Nullable PointerProperties pointerProperties) { super(failureMetadata, pointerProperties); this.actual = pointerProperties; }
Example #21
Source File: PointerPropertiesSubject.java From android-test with Apache License 2.0 | 4 votes |
public void isEqualTo(PointerProperties other) { check("id").that(actual.id).isEqualTo(other.id); check("toolType").that(actual.toolType).isEqualTo(other.toolType); }
Example #22
Source File: MotionEventSynthesizer.java From 365browser with Apache License 2.0 | 4 votes |
public MotionEventSynthesizer(View target, WindowAndroidProvider windowProvider) { mTarget = target; mWindowProvider = windowProvider; mPointerProperties = new PointerProperties[MAX_NUM_POINTERS]; mPointerCoords = new PointerCoords[MAX_NUM_POINTERS]; }
Example #23
Source File: MyInteractionController.java From PUMA with Apache License 2.0 | 4 votes |
/** * Performs a multi-touch gesture * * Takes a series of touch coordinates for at least 2 pointers. Each pointer must have * all of its touch steps defined in an array of {@link PointerCoords}. By having the ability * to specify the touch points along the path of a pointer, the caller is able to specify * complex gestures like circles, irregular shapes etc, where each pointer may take a * different path. * * To create a single point on a pointer's touch path * <code> * PointerCoords p = new PointerCoords(); * p.x = stepX; * p.y = stepY; * p.pressure = 1; * p.size = 1; * </code> * @param touches each array of {@link PointerCoords} constitute a single pointer's touch path. * Multiple {@link PointerCoords} arrays constitute multiple pointers, each with its own * path. Each {@link PointerCoords} in an array constitute a point on a pointer's path. * @return <code>true</code> if all points on all paths are injected successfully, <code>false * </code>otherwise * @since API Level 18 */ public boolean performMultiPointerGesture(PointerCoords[]... touches) { boolean ret = true; if (touches.length < 2) { throw new IllegalArgumentException("Must provide coordinates for at least 2 pointers"); } // Get the pointer with the max steps to inject. int maxSteps = 0; for (int x = 0; x < touches.length; x++) maxSteps = (maxSteps < touches[x].length) ? touches[x].length : maxSteps; // specify the properties for each pointer as finger touch PointerProperties[] properties = new PointerProperties[touches.length]; PointerCoords[] pointerCoords = new PointerCoords[touches.length]; for (int x = 0; x < touches.length; x++) { PointerProperties prop = new PointerProperties(); prop.id = x; prop.toolType = MotionEvent.TOOL_TYPE_FINGER; properties[x] = prop; // for each pointer set the first coordinates for touch down pointerCoords[x] = touches[x][0]; } // Touch down all pointers long downTime = SystemClock.uptimeMillis(); MotionEvent event; event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); for (int x = 1; x < touches.length; x++) { event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), getPointerAction(MotionEvent.ACTION_POINTER_DOWN, x), x + 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); } // Move all pointers for (int i = 1; i < maxSteps - 1; i++) { // for each pointer for (int x = 0; x < touches.length; x++) { // check if it has coordinates to move if (touches[x].length > i) pointerCoords[x] = touches[x][i]; else pointerCoords[x] = touches[x][touches[x].length - 1]; } event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, touches.length, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS); } // For each pointer get the last coordinates for (int x = 0; x < touches.length; x++) pointerCoords[x] = touches[x][touches[x].length - 1]; // touch up for (int x = 1; x < touches.length; x++) { event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), getPointerAction(MotionEvent.ACTION_POINTER_UP, x), x + 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); } Log.i(LOG_TAG, "x " + pointerCoords[0].x); // first to touch down is last up event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); return ret; }
Example #24
Source File: Swiper.java From AndroidRipper with GNU Affero General Public License v3.0 | 4 votes |
public void generateSwipeGesture(PointF startPoint1, PointF startPoint2, PointF endPoint1, PointF endPoint2) { long downTime = SystemClock.uptimeMillis(); long eventTime = SystemClock.uptimeMillis(); float startX1 = startPoint1.x; float startY1 = startPoint1.y; float startX2 = startPoint2.x; float startY2 = startPoint2.y; float endX1 = endPoint1.x; float endY1 = endPoint1.y; float endX2 = endPoint2.x; float endY2 = endPoint2.y; // pointer 1 float x1 = startX1; float y1 = startY1; // pointer 2 float x2 = startX2; float y2 = startY2; PointerCoords[] pointerCoords = new PointerCoords[2]; PointerCoords pc1 = new PointerCoords(); PointerCoords pc2 = new PointerCoords(); pc1.x = x1; pc1.y = y1; pc1.pressure = 1; pc1.size = 1; pc2.x = x2; pc2.y = y2; pc2.pressure = 1; pc2.size = 1; pointerCoords[0] = pc1; pointerCoords[1] = pc2; PointerProperties[] pointerProperties = new PointerProperties[2]; PointerProperties pp1 = new PointerProperties(); PointerProperties pp2 = new PointerProperties(); pp1.id = 0; pp1.toolType = MotionEvent.TOOL_TYPE_FINGER; pp2.id = 1; pp2.toolType = MotionEvent.TOOL_TYPE_FINGER; pointerProperties[0] = pp1; pointerProperties[1] = pp2; MotionEvent event; // send the initial touches event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 1, pointerProperties, pointerCoords, 0, 0, // metaState, buttonState 1, // x precision 1, // y precision 0, 0, 0, 0); // deviceId, edgeFlags, source, flags _instrument.sendPointerSync(event); event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_DOWN + (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); _instrument.sendPointerSync(event); int numMoves = GESTURE_DURATION_MS / EVENT_TIME_INTERVAL_MS; float stepX1 = (endX1 - startX1) / numMoves; float stepY1 = (endY1 - startY1) / numMoves; float stepX2 = (endX2 - startX2) / numMoves; float stepY2 = (endY2 - startY2) / numMoves; // send the zoom for (int i = 0; i < numMoves; i++) { eventTime += EVENT_TIME_INTERVAL_MS; pointerCoords[0].x += stepX1; pointerCoords[0].y += stepY1; pointerCoords[1].x += stepX2; pointerCoords[1].y += stepY2; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 2, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0); _instrument.sendPointerSync(event); } }
Example #25
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 4 votes |
PointerProperties getProperties() { return mProperties; }
Example #26
Source File: Tapper.java From AndroidRipper with GNU Affero General Public License v3.0 | 4 votes |
public void generateTapGesture(int numTaps, PointF... points) { MotionEvent event; long downTime = SystemClock.uptimeMillis(); long eventTime = SystemClock.uptimeMillis(); // pointer 1 float x1 = points[0].x; float y1 = points[0].y; float x2 = 0; float y2 = 0; if (points.length == 2) { // pointer 2 x2 = points[1].x; y2 = points[1].y; } PointerCoords[] pointerCoords = new PointerCoords[points.length]; PointerCoords pc1 = new PointerCoords(); pc1.x = x1; pc1.y = y1; pc1.pressure = 1; pc1.size = 1; pointerCoords[0] = pc1; PointerCoords pc2 = new PointerCoords(); if (points.length == 2) { pc2.x = x2; pc2.y = y2; pc2.pressure = 1; pc2.size = 1; pointerCoords[1] = pc2; } PointerProperties[] pointerProperties = new PointerProperties[points.length]; PointerProperties pp1 = new PointerProperties(); pp1.id = 0; pp1.toolType = MotionEvent.TOOL_TYPE_FINGER; pointerProperties[0] = pp1; PointerProperties pp2 = new PointerProperties(); if (points.length == 2) { pp2.id = 1; pp2.toolType = MotionEvent.TOOL_TYPE_FINGER; pointerProperties[1] = pp2; } int i = 0; while (i != numTaps) { event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, points.length, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); _instrument.sendPointerSync(event); if (points.length == 2) { event = MotionEvent .obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_DOWN + (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT), points.length, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); _instrument.sendPointerSync(event); eventTime += EVENT_TIME_INTERVAL_MS; event = MotionEvent .obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_UP + (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT), points.length, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); _instrument.sendPointerSync(event); } eventTime += EVENT_TIME_INTERVAL_MS; event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, points.length, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); _instrument.sendPointerSync(event); i++; } }
Example #27
Source File: GenericTouchGesture.java From android-chromium with BSD 2-Clause "Simplified" License | 4 votes |
PointerProperties getProperties() { return mProperties; }
Example #28
Source File: InteractionController.java From za-Farmer with MIT License | 4 votes |
/** * Performs a multi-touch gesture * * Takes a series of touch coordinates for at least 2 pointers. Each pointer must have * all of its touch steps defined in an array of {@link PointerCoords}. By having the ability * to specify the touch points along the path of a pointer, the caller is able to specify * complex gestures like circles, irregular shapes etc, where each pointer may take a * different path. * * To create a single point on a pointer's touch path * <code> * PointerCoords p = new PointerCoords(); * p.x = stepX; * p.y = stepY; * p.pressure = 1; * p.size = 1; * </code> * @param touches each array of {@link PointerCoords} constitute a single pointer's touch path. * Multiple {@link PointerCoords} arrays constitute multiple pointers, each with its own * path. Each {@link PointerCoords} in an array constitute a point on a pointer's path. * @return <code>true</code> if all points on all paths are injected successfully, <code>false * </code>otherwise * @since API Level 18 */ public boolean performMultiPointerGesture(PointerCoords[] ... touches) { boolean ret = true; if (touches.length < 2) { throw new IllegalArgumentException("Must provide coordinates for at least 2 pointers"); } // Get the pointer with the max steps to inject. int maxSteps = 0; for (int x = 0; x < touches.length; x++) maxSteps = (maxSteps < touches[x].length) ? touches[x].length : maxSteps; // specify the properties for each pointer as finger touch PointerProperties[] properties = new PointerProperties[touches.length]; PointerCoords[] pointerCoords = new PointerCoords[touches.length]; for (int x = 0; x < touches.length; x++) { PointerProperties prop = new PointerProperties(); prop.id = x; prop.toolType = MotionEvent.TOOL_TYPE_FINGER; properties[x] = prop; // for each pointer set the first coordinates for touch down pointerCoords[x] = touches[x][0]; } // Touch down all pointers long downTime = SystemClock.uptimeMillis(); MotionEvent event; event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); for (int x = 1; x < touches.length; x++) { event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), getPointerAction(MotionEvent.ACTION_POINTER_DOWN, x), x + 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); } // Move all pointers for (int i = 1; i < maxSteps - 1; i++) { // for each pointer for (int x = 0; x < touches.length; x++) { // check if it has coordinates to move if (touches[x].length > i) pointerCoords[x] = touches[x][i]; else pointerCoords[x] = touches[x][touches[x].length - 1]; } event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, touches.length, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); SystemClock.sleep(MOTION_EVENT_INJECTION_DELAY_MILLIS); } // For each pointer get the last coordinates for (int x = 0; x < touches.length; x++) pointerCoords[x] = touches[x][touches[x].length - 1]; // touch up for (int x = 1; x < touches.length; x++) { event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), getPointerAction(MotionEvent.ACTION_POINTER_UP, x), x + 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); } Log.i(LOG_TAG, "x " + pointerCoords[0].x); // first to touch down is last up event = MotionEvent.obtain(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 1, properties, pointerCoords, 0, 0, 1, 1, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0); ret &= injectEventSync(event); return ret; }