version:1.5
fix:迁移到奥乐云平台 add:
This commit is contained in:
275
tests/src/com/aoleyun/os/testcomponent/TouchEventGenerator.java
Normal file
275
tests/src/com/aoleyun/os/testcomponent/TouchEventGenerator.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.aoleyun.os.testcomponent;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.util.Pair;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
import android.view.MotionEvent.PointerProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class to generate MotionEvent event sequences for testing touch gesture detectors.
|
||||
*/
|
||||
public class TouchEventGenerator {
|
||||
|
||||
/**
|
||||
* Amount of time between two generated events.
|
||||
*/
|
||||
private static final long TIME_INCREMENT_MS = 20L;
|
||||
|
||||
/**
|
||||
* Id of the fake device generating the events.
|
||||
*/
|
||||
private static final int DEVICE_ID = 2104;
|
||||
|
||||
/**
|
||||
* The fingers currently present on the emulated touch screen.
|
||||
*/
|
||||
private Map<Integer, Point> mFingers;
|
||||
|
||||
/**
|
||||
* Initial event time for the current sequence.
|
||||
*/
|
||||
private long mInitialTime;
|
||||
|
||||
/**
|
||||
* Time of the last generated event.
|
||||
*/
|
||||
private long mLastEventTime;
|
||||
|
||||
/**
|
||||
* Time of the next event.
|
||||
*/
|
||||
private long mTime;
|
||||
|
||||
/**
|
||||
* Receives the generated events.
|
||||
*/
|
||||
public interface Listener {
|
||||
|
||||
/**
|
||||
* Called when an event was generated.
|
||||
*/
|
||||
void onTouchEvent(MotionEvent event);
|
||||
}
|
||||
private final Listener mListener;
|
||||
|
||||
public TouchEventGenerator(Listener listener) {
|
||||
mListener = listener;
|
||||
mFingers = new HashMap<Integer, Point>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a finger on the touchscreen.
|
||||
*/
|
||||
public TouchEventGenerator put(int id, int x, int y, long ms) {
|
||||
checkFingerExistence(id, false);
|
||||
boolean isInitialDown = mFingers.isEmpty();
|
||||
mFingers.put(id, new Point(x, y));
|
||||
int action;
|
||||
if (isInitialDown) {
|
||||
action = MotionEvent.ACTION_DOWN;
|
||||
} else {
|
||||
action = MotionEvent.ACTION_POINTER_DOWN;
|
||||
// Set the id of the changed pointer.
|
||||
action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
}
|
||||
generateEvent(action, ms);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a finger on the touchscreen after advancing default time interval.
|
||||
*/
|
||||
public TouchEventGenerator put(int id, int x, int y) {
|
||||
return put(id, x, y, TIME_INCREMENT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the position of a finger for an upcoming move event.
|
||||
*
|
||||
* @see #move(long ms)
|
||||
*/
|
||||
public TouchEventGenerator position(int id, int x, int y) {
|
||||
checkFingerExistence(id, true);
|
||||
mFingers.get(id).set(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the finger position changes of {@link #position(int, int, int)} by generating a move
|
||||
* event.
|
||||
*
|
||||
* @see #position(int, int, int)
|
||||
*/
|
||||
public TouchEventGenerator move(long ms) {
|
||||
generateEvent(MotionEvent.ACTION_MOVE, ms);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the finger position changes of {@link #position(int, int, int)} by generating a move
|
||||
* event after advancing the default time interval.
|
||||
*
|
||||
* @see #position(int, int, int)
|
||||
*/
|
||||
public TouchEventGenerator move() {
|
||||
return move(TIME_INCREMENT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a single finger on the touchscreen.
|
||||
*/
|
||||
public TouchEventGenerator move(int id, int x, int y, long ms) {
|
||||
return position(id, x, y).move(ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a single finger on the touchscreen after advancing default time interval.
|
||||
*/
|
||||
public TouchEventGenerator move(int id, int x, int y) {
|
||||
return move(id, x, y, TIME_INCREMENT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing finger from the touchscreen.
|
||||
*/
|
||||
public TouchEventGenerator lift(int id, long ms) {
|
||||
checkFingerExistence(id, true);
|
||||
boolean isFinalUp = mFingers.size() == 1;
|
||||
int action;
|
||||
if (isFinalUp) {
|
||||
action = MotionEvent.ACTION_UP;
|
||||
} else {
|
||||
action = MotionEvent.ACTION_POINTER_UP;
|
||||
// Set the id of the changed pointer.
|
||||
action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
}
|
||||
generateEvent(action, ms);
|
||||
mFingers.remove(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a finger from the touchscreen.
|
||||
*/
|
||||
public TouchEventGenerator lift(int id, int x, int y, long ms) {
|
||||
checkFingerExistence(id, true);
|
||||
mFingers.get(id).set(x, y);
|
||||
return lift(id, ms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an existing finger from the touchscreen after advancing default time interval.
|
||||
*/
|
||||
public TouchEventGenerator lift(int id) {
|
||||
return lift(id, TIME_INCREMENT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels an ongoing sequence.
|
||||
*/
|
||||
public TouchEventGenerator cancel(long ms) {
|
||||
generateEvent(MotionEvent.ACTION_CANCEL, ms);
|
||||
mFingers.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels an ongoing sequence.
|
||||
*/
|
||||
public TouchEventGenerator cancel() {
|
||||
return cancel(TIME_INCREMENT_MS);
|
||||
}
|
||||
|
||||
private void checkFingerExistence(int id, boolean shouldExist) {
|
||||
if (shouldExist != mFingers.containsKey(id)) {
|
||||
throw new IllegalArgumentException(
|
||||
shouldExist ? "Finger does not exist" : "Finger already exists");
|
||||
}
|
||||
}
|
||||
|
||||
private void generateEvent(int action, long ms) {
|
||||
mTime = mLastEventTime + ms;
|
||||
Pair<PointerProperties[], PointerCoords[]> state = getFingerState();
|
||||
MotionEvent event = MotionEvent.obtain(
|
||||
mInitialTime,
|
||||
mTime,
|
||||
action,
|
||||
state.first.length,
|
||||
state.first,
|
||||
state.second,
|
||||
0 /* metaState */,
|
||||
0 /* buttonState */,
|
||||
1.0f /* xPrecision */,
|
||||
1.0f /* yPrecision */,
|
||||
DEVICE_ID,
|
||||
0 /* edgeFlags */,
|
||||
InputDevice.SOURCE_TOUCHSCREEN,
|
||||
0 /* flags */);
|
||||
mListener.onTouchEvent(event);
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
resetTime();
|
||||
}
|
||||
event.recycle();
|
||||
mLastEventTime = mTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the fingers' state expected by MotionEvent.
|
||||
*/
|
||||
private Pair<PointerProperties[], PointerCoords[]> getFingerState() {
|
||||
int nFingers = mFingers.size();
|
||||
PointerProperties[] properties = new PointerProperties[nFingers];
|
||||
PointerCoords[] coordinates = new PointerCoords[nFingers];
|
||||
|
||||
int index = 0;
|
||||
for (Map.Entry<Integer, Point> entry : mFingers.entrySet()) {
|
||||
int id = entry.getKey();
|
||||
Point location = entry.getValue();
|
||||
|
||||
PointerProperties property = new PointerProperties();
|
||||
property.id = id;
|
||||
property.toolType = MotionEvent.TOOL_TYPE_FINGER;
|
||||
properties[index] = property;
|
||||
|
||||
PointerCoords coordinate = new PointerCoords();
|
||||
coordinate.x = location.x;
|
||||
coordinate.y = location.y;
|
||||
coordinate.pressure = 1.0f;
|
||||
coordinates[index] = coordinate;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return new Pair<MotionEvent.PointerProperties[], MotionEvent.PointerCoords[]>(
|
||||
properties, coordinates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the time references for a new sequence.
|
||||
*/
|
||||
private void resetTime() {
|
||||
mInitialTime = 0L;
|
||||
mLastEventTime = -1L;
|
||||
mTime = 0L;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user