1 /* 2 * Copyright (C) 2012 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 com.android.inputmethod.latin; 18 19 import com.android.inputmethod.annotations.UsedForTesting; 20 import com.android.inputmethod.latin.utils.ResizableIntArray; 21 22 import android.util.Log; 23 24 // TODO: This class is not thread-safe. 25 public final class InputPointers { 26 private static final String TAG = InputPointers.class.getSimpleName(); 27 private final int mDefaultCapacity; 28 private final ResizableIntArray mXCoordinates; 29 private final ResizableIntArray mYCoordinates; 30 private final ResizableIntArray mPointerIds; 31 private final ResizableIntArray mTimes; 32 33 public InputPointers(int defaultCapacity) { 34 mDefaultCapacity = defaultCapacity; 35 mXCoordinates = new ResizableIntArray(defaultCapacity); 36 mYCoordinates = new ResizableIntArray(defaultCapacity); 37 mPointerIds = new ResizableIntArray(defaultCapacity); 38 mTimes = new ResizableIntArray(defaultCapacity); 39 } 40 41 public void addPointer(int index, int x, int y, int pointerId, int time) { 42 mXCoordinates.add(index, x); 43 mYCoordinates.add(index, y); 44 mPointerIds.add(index, pointerId); 45 mTimes.add(index, time); 46 } 47 48 @UsedForTesting 49 void addPointer(int x, int y, int pointerId, int time) { 50 mXCoordinates.add(x); 51 mYCoordinates.add(y); 52 mPointerIds.add(pointerId); 53 mTimes.add(time); 54 } 55 56 public void set(InputPointers ip) { 57 mXCoordinates.set(ip.mXCoordinates); 58 mYCoordinates.set(ip.mYCoordinates); 59 mPointerIds.set(ip.mPointerIds); 60 mTimes.set(ip.mTimes); 61 } 62 63 public void copy(InputPointers ip) { 64 mXCoordinates.copy(ip.mXCoordinates); 65 mYCoordinates.copy(ip.mYCoordinates); 66 mPointerIds.copy(ip.mPointerIds); 67 mTimes.copy(ip.mTimes); 68 } 69 70 /** 71 * Append the pointers in the specified {@link InputPointers} to the end of this. 72 * @param src the source {@link InputPointers} to read the data from. 73 * @param startPos the starting index of the pointers in {@code src}. 74 * @param length the number of pointers to be appended. 75 */ 76 @UsedForTesting 77 void append(InputPointers src, int startPos, int length) { 78 if (length == 0) { 79 return; 80 } 81 mXCoordinates.append(src.mXCoordinates, startPos, length); 82 mYCoordinates.append(src.mYCoordinates, startPos, length); 83 mPointerIds.append(src.mPointerIds, startPos, length); 84 mTimes.append(src.mTimes, startPos, length); 85 } 86 87 /** 88 * Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray} 89 * to the end of this. 90 * @param pointerId the pointer id of the source. 91 * @param times the source {@link ResizableIntArray} to read the event times from. 92 * @param xCoordinates the source {@link ResizableIntArray} to read the x-coordinates from. 93 * @param yCoordinates the source {@link ResizableIntArray} to read the y-coordinates from. 94 * @param startPos the starting index of the data in {@code times} and etc. 95 * @param length the number of data to be appended. 96 */ 97 public void append(int pointerId, ResizableIntArray times, ResizableIntArray xCoordinates, 98 ResizableIntArray yCoordinates, int startPos, int length) { 99 if (length == 0) { 100 return; 101 } 102 mXCoordinates.append(xCoordinates, startPos, length); 103 mYCoordinates.append(yCoordinates, startPos, length); 104 mPointerIds.fill(pointerId, mPointerIds.getLength(), length); 105 mTimes.append(times, startPos, length); 106 } 107 108 /** 109 * Shift to the left by elementCount, discarding elementCount pointers at the start. 110 * @param elementCount how many elements to shift. 111 */ 112 public void shift(final int elementCount) { 113 mXCoordinates.shift(elementCount); 114 mYCoordinates.shift(elementCount); 115 mPointerIds.shift(elementCount); 116 mTimes.shift(elementCount); 117 } 118 119 public void reset() { 120 final int defaultCapacity = mDefaultCapacity; 121 mXCoordinates.reset(defaultCapacity); 122 mYCoordinates.reset(defaultCapacity); 123 mPointerIds.reset(defaultCapacity); 124 mTimes.reset(defaultCapacity); 125 } 126 127 public int getPointerSize() { 128 return mXCoordinates.getLength(); 129 } 130 131 public int[] getXCoordinates() { 132 return mXCoordinates.getPrimitiveArray(); 133 } 134 135 public int[] getYCoordinates() { 136 return mYCoordinates.getPrimitiveArray(); 137 } 138 139 public int[] getPointerIds() { 140 return mPointerIds.getPrimitiveArray(); 141 } 142 143 public int[] getTimes() { 144 if (LatinImeLogger.sDBG) { 145 if (!isValidTimeStamps()) { 146 throw new RuntimeException("Time stamps are invalid."); 147 } 148 } 149 return mTimes.getPrimitiveArray(); 150 } 151 152 @Override 153 public String toString() { 154 return "size=" + getPointerSize() + " id=" + mPointerIds + " time=" + mTimes 155 + " x=" + mXCoordinates + " y=" + mYCoordinates; 156 } 157 158 private boolean isValidTimeStamps() { 159 final int[] times = mTimes.getPrimitiveArray(); 160 for (int i = 1; i < getPointerSize(); ++i) { 161 if (times[i] < times[i - 1]) { 162 // dump 163 for (int j = 0; j < times.length; ++j) { 164 Log.d(TAG, "--- (" + j + ") " + times[j]); 165 } 166 return false; 167 } 168 } 169 return true; 170 } 171 } 172