1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.inputmethod.keyboard.internal; 18 19import android.util.Log; 20 21import com.android.inputmethod.latin.CollectionUtils; 22 23import java.util.ArrayList; 24 25public final class PointerTrackerQueue { 26 private static final String TAG = PointerTrackerQueue.class.getSimpleName(); 27 private static final boolean DEBUG = false; 28 29 public interface Element { 30 public boolean isModifier(); 31 public boolean isInSlidingKeyInput(); 32 public void onPhantomUpEvent(long eventTime); 33 } 34 35 private static final int INITIAL_CAPACITY = 10; 36 private final ArrayList<Element> mExpandableArrayOfActivePointers = 37 CollectionUtils.newArrayList(INITIAL_CAPACITY); 38 private int mArraySize = 0; 39 40 public synchronized int size() { 41 return mArraySize; 42 } 43 44 public synchronized void add(final Element pointer) { 45 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 46 final int arraySize = mArraySize; 47 if (arraySize < expandableArray.size()) { 48 expandableArray.set(arraySize, pointer); 49 } else { 50 expandableArray.add(pointer); 51 } 52 mArraySize = arraySize + 1; 53 } 54 55 public synchronized void remove(final Element pointer) { 56 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 57 final int arraySize = mArraySize; 58 int newSize = 0; 59 for (int index = 0; index < arraySize; index++) { 60 final Element element = expandableArray.get(index); 61 if (element == pointer) { 62 if (newSize != index) { 63 Log.w(TAG, "Found duplicated element in remove: " + pointer); 64 } 65 continue; // Remove this element from the expandableArray. 66 } 67 if (newSize != index) { 68 // Shift this element toward the beginning of the expandableArray. 69 expandableArray.set(newSize, element); 70 } 71 newSize++; 72 } 73 mArraySize = newSize; 74 } 75 76 public synchronized Element getOldestElement() { 77 return (mArraySize == 0) ? null : mExpandableArrayOfActivePointers.get(0); 78 } 79 80 public synchronized void releaseAllPointersOlderThan(final Element pointer, 81 final long eventTime) { 82 if (DEBUG) { 83 Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this); 84 } 85 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 86 final int arraySize = mArraySize; 87 int newSize, index; 88 for (newSize = index = 0; index < arraySize; index++) { 89 final Element element = expandableArray.get(index); 90 if (element == pointer) { 91 break; // Stop releasing elements. 92 } 93 if (!element.isModifier()) { 94 element.onPhantomUpEvent(eventTime); 95 continue; // Remove this element from the expandableArray. 96 } 97 if (newSize != index) { 98 // Shift this element toward the beginning of the expandableArray. 99 expandableArray.set(newSize, element); 100 } 101 newSize++; 102 } 103 // Shift rest of the expandableArray. 104 int count = 0; 105 for (; index < arraySize; index++) { 106 final Element element = expandableArray.get(index); 107 if (element == pointer) { 108 if (count > 0) { 109 Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: " 110 + pointer); 111 } 112 count++; 113 } 114 if (newSize != index) { 115 expandableArray.set(newSize, expandableArray.get(index)); 116 newSize++; 117 } 118 } 119 mArraySize = newSize; 120 } 121 122 public void releaseAllPointers(final long eventTime) { 123 releaseAllPointersExcept(null, eventTime); 124 } 125 126 public synchronized void releaseAllPointersExcept(final Element pointer, 127 final long eventTime) { 128 if (DEBUG) { 129 if (pointer == null) { 130 Log.d(TAG, "releaseAllPoniters: " + this); 131 } else { 132 Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this); 133 } 134 } 135 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 136 final int arraySize = mArraySize; 137 int newSize = 0, count = 0; 138 for (int index = 0; index < arraySize; index++) { 139 final Element element = expandableArray.get(index); 140 if (element == pointer) { 141 if (count > 0) { 142 Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + pointer); 143 } 144 count++; 145 } else { 146 element.onPhantomUpEvent(eventTime); 147 continue; // Remove this element from the expandableArray. 148 } 149 if (newSize != index) { 150 // Shift this element toward the beginning of the expandableArray. 151 expandableArray.set(newSize, element); 152 } 153 newSize++; 154 } 155 mArraySize = newSize; 156 } 157 158 public synchronized boolean hasModifierKeyOlderThan(final Element pointer) { 159 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 160 final int arraySize = mArraySize; 161 for (int index = 0; index < arraySize; index++) { 162 final Element element = expandableArray.get(index); 163 if (element == pointer) { 164 return false; // Stop searching modifier key. 165 } 166 if (element.isModifier()) { 167 return true; 168 } 169 } 170 return false; 171 } 172 173 public synchronized boolean isAnyInSlidingKeyInput() { 174 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 175 final int arraySize = mArraySize; 176 for (int index = 0; index < arraySize; index++) { 177 final Element element = expandableArray.get(index); 178 if (element.isInSlidingKeyInput()) { 179 return true; 180 } 181 } 182 return false; 183 } 184 185 @Override 186 public synchronized String toString() { 187 final StringBuilder sb = new StringBuilder(); 188 final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; 189 final int arraySize = mArraySize; 190 for (int index = 0; index < arraySize; index++) { 191 final Element element = expandableArray.get(index); 192 if (sb.length() > 0) 193 sb.append(" "); 194 sb.append(element.toString()); 195 } 196 return "[" + sb.toString() + "]"; 197 } 198} 199