[Rlog48c] Replay historical motion data
Change-Id: Ib398ea61ff048b1a4ac3b7f7b4a772e173a7b294main
parent
ce9e7f667d
commit
7708bcf6fb
|
@ -19,6 +19,8 @@ package com.android.inputmethod.research;
|
||||||
import android.util.JsonReader;
|
import android.util.JsonReader;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.MotionEvent.PointerCoords;
|
||||||
|
import android.view.MotionEvent.PointerProperties;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.define.ProductionFlag;
|
import com.android.inputmethod.latin.define.ProductionFlag;
|
||||||
|
|
||||||
|
@ -33,6 +35,14 @@ import java.util.ArrayList;
|
||||||
public class MotionEventReader {
|
public class MotionEventReader {
|
||||||
private static final String TAG = MotionEventReader.class.getSimpleName();
|
private static final String TAG = MotionEventReader.class.getSimpleName();
|
||||||
private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
|
private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
|
||||||
|
// Assumes that MotionEvent.ACTION_MASK does not have all bits set.`
|
||||||
|
private static final int UNINITIALIZED_ACTION = ~MotionEvent.ACTION_MASK;
|
||||||
|
// No legitimate int is negative
|
||||||
|
private static final int UNINITIALIZED_INT = -1;
|
||||||
|
// No legitimate long is negative
|
||||||
|
private static final long UNINITIALIZED_LONG = -1L;
|
||||||
|
// No legitimate float is negative
|
||||||
|
private static final float UNINITIALIZED_FLOAT = -1.0f;
|
||||||
|
|
||||||
public ReplayData readMotionEventData(final File file) {
|
public ReplayData readMotionEventData(final File file) {
|
||||||
final ReplayData replayData = new ReplayData();
|
final ReplayData replayData = new ReplayData();
|
||||||
|
@ -55,19 +65,82 @@ public class MotionEventReader {
|
||||||
|
|
||||||
static class ReplayData {
|
static class ReplayData {
|
||||||
final ArrayList<Integer> mActions = new ArrayList<Integer>();
|
final ArrayList<Integer> mActions = new ArrayList<Integer>();
|
||||||
final ArrayList<Integer> mXCoords = new ArrayList<Integer>();
|
final ArrayList<PointerProperties[]> mPointerPropertiesArrays
|
||||||
final ArrayList<Integer> mYCoords = new ArrayList<Integer>();
|
= new ArrayList<PointerProperties[]>();
|
||||||
|
final ArrayList<PointerCoords[]> mPointerCoordsArrays = new ArrayList<PointerCoords[]>();
|
||||||
final ArrayList<Long> mTimes = new ArrayList<Long>();
|
final ArrayList<Long> mTimes = new ArrayList<Long>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readLogStatement(final JsonReader jsonReader, final ReplayData replayData)
|
/**
|
||||||
throws IOException {
|
* Read motion data from a logStatement and store it in {@code replayData}.
|
||||||
|
*
|
||||||
|
* Two kinds of logStatements can be read. In the first variant, the MotionEvent data is
|
||||||
|
* represented as attributes at the top level like so:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {
|
||||||
|
* "_ct": 1359590400000,
|
||||||
|
* "_ut": 4381933,
|
||||||
|
* "_ty": "MotionEvent",
|
||||||
|
* "action": "UP",
|
||||||
|
* "isLoggingRelated": false,
|
||||||
|
* "x": 100,
|
||||||
|
* "y": 200
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* In the second variant, there is a separate attribute for the MotionEvent that includes
|
||||||
|
* historical data if present:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {
|
||||||
|
* "_ct": 135959040000,
|
||||||
|
* "_ut": 4382702,
|
||||||
|
* "_ty": "MotionEvent",
|
||||||
|
* "action": "MOVE",
|
||||||
|
* "isLoggingRelated": false,
|
||||||
|
* "motionEvent": {
|
||||||
|
* "pointerIds": [
|
||||||
|
* 0
|
||||||
|
* ],
|
||||||
|
* "xyt": [
|
||||||
|
* {
|
||||||
|
* "t": 4382551,
|
||||||
|
* "d": [
|
||||||
|
* {
|
||||||
|
* "x": 141.25,
|
||||||
|
* "y": 151.8485107421875,
|
||||||
|
* "toma": 101.82337188720703,
|
||||||
|
* "tomi": 101.82337188720703,
|
||||||
|
* "o": 0.0
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "t": 4382559,
|
||||||
|
* "d": [
|
||||||
|
* {
|
||||||
|
* "x": 140.7266082763672,
|
||||||
|
* "y": 151.8485107421875,
|
||||||
|
* "toma": 101.82337188720703,
|
||||||
|
* "tomi": 101.82337188720703,
|
||||||
|
* "o": 0.0
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
/* package for test */ void readLogStatement(final JsonReader jsonReader,
|
||||||
|
final ReplayData replayData) throws IOException {
|
||||||
String logStatementType = null;
|
String logStatementType = null;
|
||||||
Integer actionType = null;
|
int actionType = UNINITIALIZED_ACTION;
|
||||||
Integer x = null;
|
int x = UNINITIALIZED_INT;
|
||||||
Integer y = null;
|
int y = UNINITIALIZED_INT;
|
||||||
Long time = null;
|
long time = UNINITIALIZED_LONG;
|
||||||
boolean loggingRelated = false;
|
boolean isLoggingRelated = false;
|
||||||
|
|
||||||
jsonReader.beginObject();
|
jsonReader.beginObject();
|
||||||
while (jsonReader.hasNext()) {
|
while (jsonReader.hasNext()) {
|
||||||
|
@ -90,7 +163,18 @@ public class MotionEventReader {
|
||||||
actionType = MotionEvent.ACTION_MOVE;
|
actionType = MotionEvent.ACTION_MOVE;
|
||||||
}
|
}
|
||||||
} else if (key.equals("loggingRelated")) {
|
} else if (key.equals("loggingRelated")) {
|
||||||
loggingRelated = jsonReader.nextBoolean();
|
isLoggingRelated = jsonReader.nextBoolean();
|
||||||
|
} else if (logStatementType != null && logStatementType.equals("MotionEvent")
|
||||||
|
&& key.equals("motionEvent")) {
|
||||||
|
if (actionType == UNINITIALIZED_ACTION) {
|
||||||
|
Log.e(TAG, "no actionType assigned in MotionEvent json");
|
||||||
|
}
|
||||||
|
// Second variant of LogStatement.
|
||||||
|
if (isLoggingRelated) {
|
||||||
|
jsonReader.skipValue();
|
||||||
|
} else {
|
||||||
|
readEmbeddedMotionEvent(jsonReader, replayData, actionType);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.w(TAG, "Unknown JSON key in LogStatement: " + key);
|
Log.w(TAG, "Unknown JSON key in LogStatement: " + key);
|
||||||
|
@ -100,14 +184,149 @@ public class MotionEventReader {
|
||||||
}
|
}
|
||||||
jsonReader.endObject();
|
jsonReader.endObject();
|
||||||
|
|
||||||
if (logStatementType != null && time != null && x != null && y != null && actionType != null
|
if (logStatementType != null && time != UNINITIALIZED_LONG && x != UNINITIALIZED_INT
|
||||||
&& logStatementType.equals("MotionEvent")
|
&& y != UNINITIALIZED_INT && actionType != UNINITIALIZED_ACTION
|
||||||
&& !loggingRelated) {
|
&& logStatementType.equals("MotionEvent") && !isLoggingRelated) {
|
||||||
replayData.mActions.add(actionType);
|
// First variant of LogStatement.
|
||||||
replayData.mXCoords.add(x);
|
final PointerProperties pointerProperties = new PointerProperties();
|
||||||
replayData.mYCoords.add(y);
|
pointerProperties.id = 0;
|
||||||
replayData.mTimes.add(time);
|
pointerProperties.toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
|
||||||
|
final PointerProperties[] pointerPropertiesArray = {
|
||||||
|
pointerProperties
|
||||||
|
};
|
||||||
|
final PointerCoords pointerCoords = new PointerCoords();
|
||||||
|
pointerCoords.x = x;
|
||||||
|
pointerCoords.y = y;
|
||||||
|
pointerCoords.pressure = 1.0f;
|
||||||
|
pointerCoords.size = 1.0f;
|
||||||
|
final PointerCoords[] pointerCoordsArray = {
|
||||||
|
pointerCoords
|
||||||
|
};
|
||||||
|
addMotionEventData(replayData, actionType, time, pointerPropertiesArray,
|
||||||
|
pointerCoordsArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readEmbeddedMotionEvent(final JsonReader jsonReader, final ReplayData replayData,
|
||||||
|
final int actionType) throws IOException {
|
||||||
|
jsonReader.beginObject();
|
||||||
|
PointerProperties[] pointerPropertiesArray = null;
|
||||||
|
while (jsonReader.hasNext()) { // pointerIds/xyt
|
||||||
|
final String name = jsonReader.nextName();
|
||||||
|
if (name.equals("pointerIds")) {
|
||||||
|
pointerPropertiesArray = readPointerProperties(jsonReader);
|
||||||
|
} else if (name.equals("xyt")) {
|
||||||
|
readPointerData(jsonReader, replayData, actionType, pointerPropertiesArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PointerProperties[] readPointerProperties(final JsonReader jsonReader)
|
||||||
|
throws IOException {
|
||||||
|
final ArrayList<PointerProperties> pointerPropertiesArrayList =
|
||||||
|
new ArrayList<PointerProperties>();
|
||||||
|
jsonReader.beginArray();
|
||||||
|
while (jsonReader.hasNext()) {
|
||||||
|
final PointerProperties pointerProperties = new PointerProperties();
|
||||||
|
pointerProperties.id = jsonReader.nextInt();
|
||||||
|
pointerProperties.toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
|
||||||
|
pointerPropertiesArrayList.add(pointerProperties);
|
||||||
|
}
|
||||||
|
jsonReader.endArray();
|
||||||
|
return pointerPropertiesArrayList.toArray(
|
||||||
|
new PointerProperties[pointerPropertiesArrayList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readPointerData(final JsonReader jsonReader, final ReplayData replayData,
|
||||||
|
final int actionType, final PointerProperties[] pointerPropertiesArray)
|
||||||
|
throws IOException {
|
||||||
|
if (pointerPropertiesArray == null) {
|
||||||
|
Log.e(TAG, "PointerIDs must be given before xyt data in json for MotionEvent");
|
||||||
|
jsonReader.skipValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long time = UNINITIALIZED_LONG;
|
||||||
|
jsonReader.beginArray();
|
||||||
|
while (jsonReader.hasNext()) { // Array of historical data
|
||||||
|
jsonReader.beginObject();
|
||||||
|
final ArrayList<PointerCoords> pointerCoordsArrayList = new ArrayList<PointerCoords>();
|
||||||
|
while (jsonReader.hasNext()) { // Time/data object
|
||||||
|
final String name = jsonReader.nextName();
|
||||||
|
if (name.equals("t")) {
|
||||||
|
time = jsonReader.nextLong();
|
||||||
|
} else if (name.equals("d")) {
|
||||||
|
jsonReader.beginArray();
|
||||||
|
while (jsonReader.hasNext()) { // array of data per pointer
|
||||||
|
final PointerCoords pointerCoords = readPointerCoords(jsonReader);
|
||||||
|
if (pointerCoords != null) {
|
||||||
|
pointerCoordsArrayList.add(pointerCoords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.endArray();
|
||||||
|
} else {
|
||||||
|
jsonReader.skipValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.endObject();
|
||||||
|
// Data was recorded as historical events, but must be split apart into
|
||||||
|
// separate MotionEvents for replaying
|
||||||
|
if (time != UNINITIALIZED_LONG) {
|
||||||
|
addMotionEventData(replayData, actionType, time, pointerPropertiesArray,
|
||||||
|
pointerCoordsArrayList.toArray(
|
||||||
|
new PointerCoords[pointerCoordsArrayList.size()]));
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Time not assigned in json for MotionEvent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@code x} is uninitialized.
|
||||||
|
*
|
||||||
|
* Assumes that {@code x} will never be given a valid value less than 0, and that
|
||||||
|
* UNINITIALIZED_FLOAT is less than 0.0f.
|
||||||
|
*/
|
||||||
|
private boolean isUninitializedFloat(final float x) {
|
||||||
|
return x < 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import android.os.Message;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
import android.view.MotionEvent.PointerCoords;
|
||||||
|
import android.view.MotionEvent.PointerProperties;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
import com.android.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import com.android.inputmethod.keyboard.MainKeyboardView;
|
import com.android.inputmethod.keyboard.MainKeyboardView;
|
||||||
|
@ -62,7 +64,6 @@ public class Replayer {
|
||||||
if (mIsReplaying) {
|
if (mIsReplaying) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsReplaying = true;
|
mIsReplaying = true;
|
||||||
final int numActions = replayData.mActions.size();
|
final int numActions = replayData.mActions.size();
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
@ -95,25 +96,36 @@ public class Replayer {
|
||||||
case MSG_MOTION_EVENT:
|
case MSG_MOTION_EVENT:
|
||||||
final int index = msg.arg1;
|
final int index = msg.arg1;
|
||||||
final int action = replayData.mActions.get(index);
|
final int action = replayData.mActions.get(index);
|
||||||
final int x = replayData.mXCoords.get(index);
|
final PointerProperties[] pointerPropertiesArray =
|
||||||
final int y = replayData.mYCoords.get(index);
|
replayData.mPointerPropertiesArrays.get(index);
|
||||||
|
final PointerCoords[] pointerCoordsArray =
|
||||||
|
replayData.mPointerCoordsArrays.get(index);
|
||||||
final long origTime = replayData.mTimes.get(index);
|
final long origTime = replayData.mTimes.get(index);
|
||||||
if (action == MotionEvent.ACTION_DOWN) {
|
if (action == MotionEvent.ACTION_DOWN) {
|
||||||
mOrigDownTime = origTime;
|
mOrigDownTime = origTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
final MotionEvent me = MotionEvent.obtain(mOrigDownTime + timeAdjustment,
|
final MotionEvent me = MotionEvent.obtain(mOrigDownTime + timeAdjustment,
|
||||||
origTime + timeAdjustment, action, x, y, 0);
|
origTime + timeAdjustment, action,
|
||||||
|
pointerPropertiesArray.length, pointerPropertiesArray,
|
||||||
|
pointerCoordsArray, 0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
|
||||||
mainKeyboardView.processMotionEvent(me);
|
mainKeyboardView.processMotionEvent(me);
|
||||||
me.recycle();
|
me.recycle();
|
||||||
break;
|
break;
|
||||||
case MSG_DONE:
|
case MSG_DONE:
|
||||||
mIsReplaying = false;
|
mIsReplaying = false;
|
||||||
|
ResearchLogger.getInstance().requestIndicatorRedraw();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ResearchLogger.getInstance().requestIndicatorRedraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
for (int i = 0; i < numActions; i++) {
|
for (int i = 0; i < numActions; i++) {
|
||||||
final Message msg = Message.obtain(handler, MSG_MOTION_EVENT, i, 0);
|
final Message msg = Message.obtain(handler, MSG_MOTION_EVENT, i, 0);
|
||||||
final long msgTime = replayData.mTimes.get(i) + timeAdjustment;
|
final long msgTime = replayData.mTimes.get(i) + timeAdjustment;
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013 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.android.inputmethod.research;
|
||||||
|
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import android.util.JsonReader;
|
||||||
|
|
||||||
|
import com.android.inputmethod.research.MotionEventReader.ReplayData;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
public class MotionEventReaderTests extends AndroidTestCase {
|
||||||
|
private MotionEventReader mMotionEventReader = new MotionEventReader();
|
||||||
|
private ReplayData mReplayData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
mReplayData = new ReplayData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonReader jsonReaderForString(final String s) {
|
||||||
|
return new JsonReader(new StringReader(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTopLevelDataVariant() {
|
||||||
|
final JsonReader jsonReader = jsonReaderForString(
|
||||||
|
"{"
|
||||||
|
+ "\"_ct\": 1359590400000,"
|
||||||
|
+ "\"_ut\": 4381933,"
|
||||||
|
+ "\"_ty\": \"MotionEvent\","
|
||||||
|
+ "\"action\": \"UP\","
|
||||||
|
+ "\"isLoggingRelated\": false,"
|
||||||
|
+ "\"x\": 100.0,"
|
||||||
|
+ "\"y\": 200.0"
|
||||||
|
+ "}"
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
mMotionEventReader.readLogStatement(jsonReader, mReplayData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail("IOException thrown");
|
||||||
|
}
|
||||||
|
assertEquals("x set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].x, 100);
|
||||||
|
assertEquals("y set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].y, 200);
|
||||||
|
assertEquals("only one pointer", mReplayData.mPointerCoordsArrays.get(0).length, 1);
|
||||||
|
assertEquals("only one MotionEvent", mReplayData.mPointerCoordsArrays.size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNestedDataVariant() {
|
||||||
|
final JsonReader jsonReader = jsonReaderForString(
|
||||||
|
"{"
|
||||||
|
+ " \"_ct\": 135959040000,"
|
||||||
|
+ " \"_ut\": 4382702,"
|
||||||
|
+ " \"_ty\": \"MotionEvent\","
|
||||||
|
+ " \"action\": \"MOVE\","
|
||||||
|
+ " \"isLoggingRelated\": false,"
|
||||||
|
+ " \"motionEvent\": {"
|
||||||
|
+ " \"pointerIds\": ["
|
||||||
|
+ " 0"
|
||||||
|
+ " ],"
|
||||||
|
+ " \"xyt\": ["
|
||||||
|
+ " {"
|
||||||
|
+ " \"t\": 4382551,"
|
||||||
|
+ " \"d\": ["
|
||||||
|
+ " {"
|
||||||
|
+ " \"x\": 100.0,"
|
||||||
|
+ " \"y\": 200.0,"
|
||||||
|
+ " \"toma\": 999.0,"
|
||||||
|
+ " \"tomi\": 999.0,"
|
||||||
|
+ " \"o\": 0.0"
|
||||||
|
+ " }"
|
||||||
|
+ " ]"
|
||||||
|
+ " },"
|
||||||
|
+ " {"
|
||||||
|
+ " \"t\": 4382559,"
|
||||||
|
+ " \"d\": ["
|
||||||
|
+ " {"
|
||||||
|
+ " \"x\": 300.0,"
|
||||||
|
+ " \"y\": 400.0,"
|
||||||
|
+ " \"toma\": 999.0,"
|
||||||
|
+ " \"tomi\": 999.0,"
|
||||||
|
+ " \"o\": 0.0"
|
||||||
|
+ " }"
|
||||||
|
+ " ]"
|
||||||
|
+ " }"
|
||||||
|
+ " ]"
|
||||||
|
+ " }"
|
||||||
|
+ "}"
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
mMotionEventReader.readLogStatement(jsonReader, mReplayData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail("IOException thrown");
|
||||||
|
}
|
||||||
|
assertEquals("x1 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].x, 100);
|
||||||
|
assertEquals("y1 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].y, 200);
|
||||||
|
assertEquals("x2 set correctly", (int) mReplayData.mPointerCoordsArrays.get(1)[0].x, 300);
|
||||||
|
assertEquals("y2 set correctly", (int) mReplayData.mPointerCoordsArrays.get(1)[0].y, 400);
|
||||||
|
assertEquals("only one pointer", mReplayData.mPointerCoordsArrays.get(0).length, 1);
|
||||||
|
assertEquals("two MotionEvents", mReplayData.mPointerCoordsArrays.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNestedDataVariantMultiPointer() {
|
||||||
|
final JsonReader jsonReader = jsonReaderForString(
|
||||||
|
"{"
|
||||||
|
+ " \"_ct\": 135959040000,"
|
||||||
|
+ " \"_ut\": 4382702,"
|
||||||
|
+ " \"_ty\": \"MotionEvent\","
|
||||||
|
+ " \"action\": \"MOVE\","
|
||||||
|
+ " \"isLoggingRelated\": false,"
|
||||||
|
+ " \"motionEvent\": {"
|
||||||
|
+ " \"pointerIds\": ["
|
||||||
|
+ " 1"
|
||||||
|
+ " ],"
|
||||||
|
+ " \"xyt\": ["
|
||||||
|
+ " {"
|
||||||
|
+ " \"t\": 4382551,"
|
||||||
|
+ " \"d\": ["
|
||||||
|
+ " {"
|
||||||
|
+ " \"x\": 100.0,"
|
||||||
|
+ " \"y\": 200.0,"
|
||||||
|
+ " \"toma\": 999.0,"
|
||||||
|
+ " \"tomi\": 999.0,"
|
||||||
|
+ " \"o\": 0.0"
|
||||||
|
+ " },"
|
||||||
|
+ " {"
|
||||||
|
+ " \"x\": 300.0,"
|
||||||
|
+ " \"y\": 400.0,"
|
||||||
|
+ " \"toma\": 999.0,"
|
||||||
|
+ " \"tomi\": 999.0,"
|
||||||
|
+ " \"o\": 0.0"
|
||||||
|
+ " }"
|
||||||
|
+ " ]"
|
||||||
|
+ " }"
|
||||||
|
+ " ]"
|
||||||
|
+ " }"
|
||||||
|
+ "}"
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
mMotionEventReader.readLogStatement(jsonReader, mReplayData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail("IOException thrown");
|
||||||
|
}
|
||||||
|
assertEquals("x1 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].x, 100);
|
||||||
|
assertEquals("y1 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[0].y, 200);
|
||||||
|
assertEquals("x2 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[1].x, 300);
|
||||||
|
assertEquals("y2 set correctly", (int) mReplayData.mPointerCoordsArrays.get(0)[1].y, 400);
|
||||||
|
assertEquals("two pointers", mReplayData.mPointerCoordsArrays.get(0).length, 2);
|
||||||
|
assertEquals("one MotionEvent", mReplayData.mPointerCoordsArrays.size(), 1);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue