private void buildMouseEvents(PointerCoords coords, int clickCount) { long currMS = System.currentTimeMillis(); // mousePressed MouseEvent swingMouseEvent = new MouseEvent(JTable.this, MouseEvent.MOUSE_PRESSED, currMS, 0, (int)coords.x, (int)coords.y, clickCount, false, MouseEvent.BUTTON1); JTable.this.processMouseEventAdAPI(swingMouseEvent); //mouseReleased swingMouseEvent = new MouseEvent(JTable.this, MouseEvent.MOUSE_RELEASED, currMS, 0, (int)coords.x, (int)coords.y, clickCount, false, MouseEvent.BUTTON1); JTable.this.processMouseEventAdAPI(swingMouseEvent); //mouseClicked MouseEvent clickEvent = new MouseEvent(JTable.this, MouseEvent.MOUSE_CLICKED, currMS, 0, (int)coords.x, (int)coords.y, clickCount, false, MouseEvent.BUTTON1); JTable.this.processMouseEventAdAPI(clickEvent); }
/** * Applies all changes that were set via {@link #setMovement(int, float, float) the setMovement(...)} method. */ public void applyMovements() { int pointerCount = pointerIds.size(); PointerCoords[] coords = new PointerCoords[pointerCount]; PointerProperties[] properties = new PointerProperties[pointerCount]; int i = 0; for (Integer pointerId : pointerIds) { coords[i] = pointerPositionsMap.get(pointerId); properties[i] = pointerPropertiesMap.get(pointerId); i++; } injectMultipointMotionEvent(coords, properties); }
private void injectMultipointMotionEvent(PointerCoords[] coords, PointerProperties[] properties) { int pointerCount = coords.length; long now = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain(now, now, // when the event happened MotionEvent.ACTION_MOVE, // event type pointerCount, // number of pointers properties, // pointer properties coords, // pointer coordinate descriptors DEFAULT_META_STATE, 0, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEVICE_ID, DEFAULT_EDGE_FLAGS, DEFAULT_INPUT_SOURCE, 0 // no flags ); injectMethodFacade(event); }
@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; }
TouchPointer(int startX, int startY, int deltaX, int deltaY, int id, float scale) { mStartX = startX * scale; mStartY = startY * scale; mDeltaX = deltaX * scale; mDeltaY = deltaY * scale; 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; }
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(); mPointers = new TouchPointer[2]; mPointers[0] = new TouchPointer(startX0, startY0, deltaX0, deltaY0, 0, scale); mPointers[1] = new TouchPointer(startX1, startY1, deltaX1, deltaY1, 1, scale); 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(); }
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(); }
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(); }
@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 = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); 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; }
private static MotionEvent transformEventOld(MotionEvent e, Matrix m) { long downTime = e.getDownTime(); long eventTime = e.getEventTime(); int action = e.getAction(); int pointerCount = e.getPointerCount(); int[] pointerIds = getPointerIds(e); PointerCoords[] pointerCoords = getPointerCoords(e); int metaState = e.getMetaState(); float xPrecision = e.getXPrecision(); float yPrecision = e.getYPrecision(); int deviceId = e.getDeviceId(); int edgeFlags = e.getEdgeFlags(); int source = e.getSource(); int flags = e.getFlags(); // Copy the x and y coordinates into an array, map them, and copy back. float[] xy = new float[pointerCoords.length * 2]; for (int i = 0; i < pointerCount;i++) { xy[2 * i] = pointerCoords[i].x; xy[2 * i + 1] = pointerCoords[i].y; } m.mapPoints(xy); for (int i = 0; i < pointerCount;i++) { pointerCoords[i].x = xy[2 * i]; pointerCoords[i].y = xy[2 * i + 1]; pointerCoords[i].orientation = transformAngle( m, pointerCoords[i].orientation); } MotionEvent n = MotionEvent.obtain(downTime, eventTime, action, pointerCount, pointerIds, pointerCoords, metaState, xPrecision, yPrecision, deviceId, edgeFlags, source, flags); return n; }
private static PointerCoords[] getPointerCoords(MotionEvent e) { int n = e.getPointerCount(); PointerCoords[] r = new PointerCoords[n]; for (int i = 0; i < n; i++) { r[i] = new PointerCoords(); e.getPointerCoords(i, r[i]); } return r; }
/** * Sets the next position of a specified pointer. * * @param pointerId * - the pointer ID which has changed it's position. * @param toX * - the new X pointer position. * @param toY * - the new Y pointer position. */ public void setMovement(int pointerId, float toX, float toY) { if (!pointerPositionsMap.containsKey(pointerId)) { return; } PointerCoords pointerPosition = pointerPositionsMap.get(pointerId); pointerPosition.x = toX; pointerPosition.y = toY; // pointerPositionsMap.put(pointerId, pointerPosition); }
private void injectFingerRegisterEvent(int newPointerId) { int pointerCount = pointerIds.size(); int action = pointerCount == 1 ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_POINTER_DOWN; PointerCoords[] coords = new PointerCoords[pointerCount]; PointerProperties[] properties = new PointerProperties[pointerCount]; int i = 0; for (Integer pointerId : pointerIds) { coords[i] = pointerPositionsMap.get(pointerId); properties[i] = pointerPropertiesMap.get(pointerId); i++; } long now = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain(now, now, action, pointerCount, properties, coords, DEFAULT_META_STATE, 0, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEVICE_ID, DEFAULT_EDGE_FLAGS, DEFAULT_INPUT_SOURCE, 0); if (action == MotionEvent.ACTION_POINTER_DOWN) { int newPointerIndex = event.findPointerIndex(newPointerId); event.setAction(action | (newPointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT)); } injectMethodFacade(event); }
private void injectFingerUnregisterEvent(int upPointerId) { int pointerCount = pointerIds.size(); int action = pointerCount == 1 ? MotionEvent.ACTION_UP : MotionEvent.ACTION_POINTER_UP; PointerCoords[] coords = new PointerCoords[pointerCount]; PointerProperties[] properties = new PointerProperties[pointerCount]; int i = 0; for (Integer pointerId : pointerIds) { coords[i] = pointerPositionsMap.get(pointerId); properties[i] = pointerPropertiesMap.get(pointerId); if (upPointerId == pointerId) { coords[i].pressure = 0.0f; } i++; } long now = SystemClock.uptimeMillis(); MotionEvent event = MotionEvent.obtain(now, now, action, pointerCount, properties, coords, DEFAULT_META_STATE, 0, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEVICE_ID, DEFAULT_EDGE_FLAGS, DEFAULT_INPUT_SOURCE, 0); if (action == MotionEvent.ACTION_POINTER_UP) { int newPointerIndex = event.findPointerIndex(upPointerId); event.setAction(action | (newPointerIndex << MotionEvent.ACTION_POINTER_INDEX_SHIFT)); } injectMethodFacade(event); }
private static MotionInputEventParams toMotionEventInputParams( final int actionCode, final PointerCoords coordinates, final int button, final PointerProperties properties, final long startDelta) { final MotionInputEventParams evtParams = new MotionInputEventParams(); evtParams.actionCode = actionCode; evtParams.coordinates = coordinates; evtParams.button = button; evtParams.properties = properties; evtParams.startDelta = startDelta; return evtParams; }
private PointerCoords[][] parsePointerCoords(final IHttpRequest request) throws JSONException { final JSONArray actions = (org.json.JSONArray) getPayload(request).get("actions"); final double time = computeLongestTime(actions); final PointerCoords[][] pcs = new PointerCoords[actions.length()][]; for (int i = 0; i < actions.length(); i++) { final JSONArray gestures = actions.getJSONArray(i); pcs[i] = gesturesToPointerCoords(time, gestures); } return pcs; }
private PointerCoords[] gesturesToPointerCoords(final double maxTime, final JSONArray gestures) throws JSONException { // gestures, e.g.: // [ // {"touch":{"y":529.5,"x":120},"time":0.2}, // {"touch":{"y":529.5,"x":130},"time":0.4}, // {"touch":{"y":454.5,"x":140},"time":0.6}, // {"touch":{"y":304.5,"x":150},"time":0.8} // ] // From the docs: // "Steps are injected about 5 milliseconds apart, so 100 steps may take // around 0.5 seconds to complete." final int steps = (int) (maxTime * 200) + 2; final PointerCoords[] pc = new PointerCoords[steps]; int i = 1; JSONObject current = gestures.getJSONObject(0); double currentTime = current.getDouble("time"); double runningTime = 0.0; final int gesturesLength = gestures.length(); for (int j = 0; j < steps; j++) { if (runningTime > currentTime && i < gesturesLength) { current = gestures.getJSONObject(i++); currentTime = current.getDouble("time"); } pc[j] = createPointerCoords(current); runningTime += 0.005; } return pc; }
private PointerCoords createPointerCoords(final JSONObject obj) throws JSONException { final JSONObject o = obj.getJSONObject("touch"); final int x = o.getInt("x"); final int y = o.getInt("y"); final PointerCoords p = new PointerCoords(); p.size = 1; p.pressure = 1; p.x = x; p.y = y; return p; }
private static PointerCoords[] filterPointerCoordinates( final List<MotionInputEventParams> motionEventsParams, final boolean shouldHovering) { final List<PointerCoords> result = new ArrayList<>(); for (final MotionInputEventParams eventParams : motionEventsParams) { if (shouldHovering && HOVERING_ACTIONS.contains(eventParams.actionCode)) { result.add(eventParams.coordinates); } else if (!shouldHovering && !HOVERING_ACTIONS.contains(eventParams.actionCode)) { result.add(eventParams.coordinates); } } return result.toArray(new PointerCoords[result.size()]); }
/** * Helper functions */ private static PointerCoords[] getCoordinates(float[][] coordinates) { PointerCoords[] pointerCoordinates = new PointerCoords[]{ new PointerCoords(), new PointerCoords() }; pointerCoordinates[0].pressure = pointerCoordinates[1].pressure = 1; pointerCoordinates[0].size = pointerCoordinates[1].size = 1; pointerCoordinates[0].x = coordinates[0][0]; pointerCoordinates[0].y = coordinates[0][1]; pointerCoordinates[1].x = coordinates[1][0]; pointerCoordinates[1].y = coordinates[1][1]; return pointerCoordinates; }
GenericTouchGesture(ContentViewCore contentViewCore, int startX, int startY, int deltaX, int deltaY) { mContentViewCore = contentViewCore; float scale = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor(); mPointers = new TouchPointer[1]; mPointers[0] = new TouchPointer(startX, startY, deltaX, deltaY, 0, scale); mPointerProperties = new PointerProperties[1]; mPointerProperties[0] = mPointers[0].getProperties(); mPointerCoords = new PointerCoords[1]; mPointerCoords[0] = mPointers[0].getCoords(); }
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; }
private PointerCoords readPointerCoords(final JsonReader jsonReader) throws IOException { jsonReader.beginObject(); float x = UNINITIALIZED_FLOAT; float y = UNINITIALIZED_FLOAT; while (jsonReader.hasNext()) { // x,y final String name = jsonReader.nextName(); if (name.equals("x")) { x = (float) jsonReader.nextDouble(); } else if (name.equals("y")) { y = (float) jsonReader.nextDouble(); } else { jsonReader.skipValue(); } } jsonReader.endObject(); if (Float.compare(x, UNINITIALIZED_FLOAT) == 0 || Float.compare(y, UNINITIALIZED_FLOAT) == 0) { Log.w(TAG, "missing x or y value in MotionEvent json"); return null; } final PointerCoords pointerCoords = new PointerCoords(); pointerCoords.x = x; pointerCoords.y = y; pointerCoords.pressure = 1.0f; pointerCoords.size = 1.0f; return pointerCoords; }
private void addMotionEventData(final ReplayData replayData, final int actionType, final long time, final PointerProperties[] pointerProperties, final PointerCoords[] pointerCoords) { replayData.mActions.add(actionType); replayData.mTimes.add(time); replayData.mPointerPropertiesArrays.add(pointerProperties); replayData.mPointerCoordsArrays.add(pointerCoords); }
private PointerCoords[] getPointerCoords () { PointerCoords[] pointerCoords = new PointerCoords[pointers.size()]; int i = 0; for(Pointer p : pointers) { pointerCoords[i++] = p.getCoords(); } return pointerCoords; }
private static PointerCoords extractElementCoordinates( final String actionId, final JSONObject actionItem, final Object originValue) throws JSONException { String elementId = null; if (originValue instanceof String) { elementId = (String) originValue; } else if (originValue instanceof JSONObject) { // It's how this is defined in WebDriver source: // // if isinstance(origin, WebElement): // action["origin"] = {"element-6066-11e4-a52e-4f735466cecf": origin.id} final Iterator<String> keys = ((JSONObject) originValue).keys(); if (keys.hasNext()) { final String name = keys.next(); if (name.toLowerCase().startsWith("element")) { elementId = String.valueOf(((JSONObject) originValue).get(name)); } } } if (elementId == null) { throw new ActionsParseException(String.format( "An unknown element '%s' is set for action item '%s' of action '%s'", originValue, actionItem, actionId)); } final PointerCoords result = new PointerCoords(); Rect bounds; try { final AndroidElement element = KnownElements.getElementFromCache(elementId); bounds = element.getBounds(); if (bounds.width() == 0 || bounds.height() == 0) { throw new ActionsParseException(String.format( "The element with id '%s' has zero width/height in the action item '%s' of action '%s'", elementId, actionItem, actionId)); } } catch (NullPointerException | UiObjectNotFoundException e) { throw new ActionsParseException(String.format( "An unknown element id '%s' is set for the action item '%s' of action '%s'", elementId, actionItem, actionId)); } // https://w3c.github.io/webdriver/webdriver-spec.html#pointer-actions // > Let x element and y element be the result of calculating the in-view center point of element. result.x = bounds.left + bounds.width() / 2; result.y = bounds.top + bounds.height() / 2; if (actionItem.has(ACTION_ITEM_X_KEY)) { result.x += (float) actionItem.getDouble(ACTION_ITEM_X_KEY); // TODO: Shall we throw an exception if result.x is outside of bounds rect? } if (actionItem.has(ACTION_ITEM_Y_KEY)) { result.y += (float) actionItem.getDouble(ACTION_ITEM_Y_KEY); // TODO: Shall we throw an exception if result.y is outside of bounds rect? } return result; }
private static PointerCoords extractCoordinates(final String actionId, final JSONArray allItems, final int itemIdx) throws JSONException { if (itemIdx < 0) { throw new ActionsParseException(String.format( "The first item of action '%s' cannot define HOVER move, " + "because its start coordinates are not set", actionId)); } final JSONObject actionItem = allItems.getJSONObject(itemIdx); final String actionType = actionItem.getString(ACTION_ITEM_TYPE_KEY); if (!actionType.equals(ACTION_ITEM_TYPE_POINTER_MOVE)) { if (itemIdx > 0) { return extractCoordinates(actionId, allItems, itemIdx - 1); } throw new ActionsParseException(String.format( "Action item '%s' of action '%s' should be preceded with at least one item " + "with coordinates", actionItem, actionId)); } Object origin = ACTION_ITEM_ORIGIN_VIEWPORT; if (actionItem.has(ACTION_ITEM_ORIGIN_KEY)) { origin = actionItem.get(ACTION_ITEM_ORIGIN_KEY); } final PointerCoords result = new PointerCoords(); result.size = actionItem.has(ACTION_ITEM_SIZE_KEY) ? (float) actionItem.getDouble(ACTION_ITEM_SIZE_KEY) : 1; result.pressure = actionItem.has(ACTION_ITEM_PRESSURE_KEY) ? (float) actionItem.getDouble(ACTION_ITEM_PRESSURE_KEY) : 1; if (origin instanceof String) { if (origin.equals(ACTION_ITEM_ORIGIN_VIEWPORT)) { if (!actionItem.has(ACTION_ITEM_X_KEY) || !actionItem.has(ACTION_ITEM_Y_KEY)) { throw new ActionsParseException(String.format( "Both coordinates must be be set for action item '%s' of action '%s'", actionItem, actionId)); } result.x = (float) actionItem.getDouble(ACTION_ITEM_X_KEY); result.y = (float) actionItem.getDouble(ACTION_ITEM_Y_KEY); return result; } else if (origin.equals(ACTION_ITEM_ORIGIN_POINTER)) { if (itemIdx > 0) { final PointerCoords recentCoords = extractCoordinates(actionId, allItems, itemIdx - 1); result.x = recentCoords.x; result.y = recentCoords.y; if (actionItem.has(ACTION_ITEM_X_KEY)) { result.x += (float) actionItem.getDouble(ACTION_ITEM_X_KEY); } if (actionItem.has(ACTION_ITEM_Y_KEY)) { result.y += (float) actionItem.getDouble(ACTION_ITEM_Y_KEY); } return result; } throw new ActionsParseException(String.format( "Action item '%s' of action '%s' should be preceded with at least one item " + "containing absolute coordinates", actionItem, actionId)); } } return extractElementCoordinates(actionId, actionItem, origin); }
public Boolean performMultiPointerGesture(PointerCoords[][] pcs) throws UiAutomator2Exception { return (Boolean) invoke(method(CLASS_INTERACTION_CONTROLLER, METHOD_PERFORM_MULTI_POINTER_GESTURE, PointerCoords[][].class), interactionController, (Object) pcs); }
final MotionEvent.PointerCoords a(long paramLong) { ghy localghy; if (paramLong <= a()) { localghy = (ghy)this.a.get(0); } for (;;) { float f2; if (paramLong <= localghy.i) { f2 = 0.0F; } for (;;) { PointF localPointF = localghy.a(efj.a(f2 * localghy.c, 0.0F, localghy.c)); float f3 = localghy.d + f2 * localghy.f; MotionEvent.PointerCoords localPointerCoords = new MotionEvent.PointerCoords(); localPointerCoords.x = localPointF.x; localPointerCoords.y = localPointF.y; localPointerCoords.touchMinor = f3; localPointerCoords.touchMajor = f3; localPointerCoords.pressure = (f3 / localghy.g); return localPointerCoords; if (paramLong >= b()) { localghy = (ghy)this.a.get(-1 + this.a.size()); break; } Iterator localIterator = this.a.iterator(); do { if (!localIterator.hasNext()) { break; } localghy = (ghy)localIterator.next(); } while ((localghy.i > paramLong) || (paramLong > localghy.j)); break; if (paramLong >= localghy.j) { f2 = 1.0F; } else { float f1 = (float)(paramLong - localghy.i) / (float)localghy.h; f2 = localghy.a.getInterpolation(f1); } } localghy = null; } }
public MotionEventSynthesizer(View target, WindowAndroidProvider windowProvider) { mTarget = target; mWindowProvider = windowProvider; mPointerProperties = new PointerProperties[MAX_NUM_POINTERS]; mPointerCoords = new PointerCoords[MAX_NUM_POINTERS]; }
PointerCoords getCoords() { return mCoords; }