PointerTrackerQueue.java revision 8aa9963a895f9dd5bb1bc92ab2e4f461e058f87a
1/*
2 * Copyright (C) 2010 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
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        public void cancelTracking();
34    }
35
36    private static final int INITIAL_CAPACITY = 10;
37    private final ArrayList<Element> mExpandableArrayOfActivePointers =
38            CollectionUtils.newArrayList(INITIAL_CAPACITY);
39    private int mArraySize = 0;
40
41    public synchronized int size() {
42        return mArraySize;
43    }
44
45    public synchronized void add(final Element pointer) {
46        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
47        final int arraySize = mArraySize;
48        if (arraySize < expandableArray.size()) {
49            expandableArray.set(arraySize, pointer);
50        } else {
51            expandableArray.add(pointer);
52        }
53        mArraySize = arraySize + 1;
54    }
55
56    public synchronized void remove(final Element pointer) {
57        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
58        final int arraySize = mArraySize;
59        int newSize = 0;
60        for (int index = 0; index < arraySize; index++) {
61            final Element element = expandableArray.get(index);
62            if (element == pointer) {
63                if (newSize != index) {
64                    Log.w(TAG, "Found duplicated element in remove: " + pointer);
65                }
66                continue; // Remove this element from the expandableArray.
67            }
68            if (newSize != index) {
69                // Shift this element toward the beginning of the expandableArray.
70                expandableArray.set(newSize, element);
71            }
72            newSize++;
73        }
74        mArraySize = newSize;
75    }
76
77    public synchronized Element getOldestElement() {
78        return (mArraySize == 0) ? null : mExpandableArrayOfActivePointers.get(0);
79    }
80
81    public synchronized void releaseAllPointersOlderThan(final Element pointer,
82            final long eventTime) {
83        if (DEBUG) {
84            Log.d(TAG, "releaseAllPoniterOlderThan: " + pointer + " " + this);
85        }
86        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
87        final int arraySize = mArraySize;
88        int newSize, index;
89        for (newSize = index = 0; index < arraySize; index++) {
90            final Element element = expandableArray.get(index);
91            if (element == pointer) {
92                break; // Stop releasing elements.
93            }
94            if (!element.isModifier()) {
95                element.onPhantomUpEvent(eventTime);
96                continue; // Remove this element from the expandableArray.
97            }
98            if (newSize != index) {
99                // Shift this element toward the beginning of the expandableArray.
100                expandableArray.set(newSize, element);
101            }
102            newSize++;
103        }
104        // Shift rest of the expandableArray.
105        int count = 0;
106        for (; index < arraySize; index++) {
107            final Element element = expandableArray.get(index);
108            if (element == pointer) {
109                if (count > 0) {
110                    Log.w(TAG, "Found duplicated element in releaseAllPointersOlderThan: "
111                            + pointer);
112                }
113                count++;
114            }
115            if (newSize != index) {
116                expandableArray.set(newSize, expandableArray.get(index));
117                newSize++;
118            }
119        }
120        mArraySize = newSize;
121    }
122
123    public void releaseAllPointers(final long eventTime) {
124        releaseAllPointersExcept(null, eventTime);
125    }
126
127    public synchronized void releaseAllPointersExcept(final Element pointer,
128            final long eventTime) {
129        if (DEBUG) {
130            if (pointer == null) {
131                Log.d(TAG, "releaseAllPoniters: " + this);
132            } else {
133                Log.d(TAG, "releaseAllPoniterExcept: " + pointer + " " + this);
134            }
135        }
136        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
137        final int arraySize = mArraySize;
138        int newSize = 0, count = 0;
139        for (int index = 0; index < arraySize; index++) {
140            final Element element = expandableArray.get(index);
141            if (element == pointer) {
142                if (count > 0) {
143                    Log.w(TAG, "Found duplicated element in releaseAllPointersExcept: " + pointer);
144                }
145                count++;
146            } else {
147                element.onPhantomUpEvent(eventTime);
148                continue; // Remove this element from the expandableArray.
149            }
150            if (newSize != index) {
151                // Shift this element toward the beginning of the expandableArray.
152                expandableArray.set(newSize, element);
153            }
154            newSize++;
155        }
156        mArraySize = newSize;
157    }
158
159    public synchronized boolean hasModifierKeyOlderThan(final Element pointer) {
160        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
161        final int arraySize = mArraySize;
162        for (int index = 0; index < arraySize; index++) {
163            final Element element = expandableArray.get(index);
164            if (element == pointer) {
165                return false; // Stop searching modifier key.
166            }
167            if (element.isModifier()) {
168                return true;
169            }
170        }
171        return false;
172    }
173
174    public synchronized boolean isAnyInSlidingKeyInput() {
175        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
176        final int arraySize = mArraySize;
177        for (int index = 0; index < arraySize; index++) {
178            final Element element = expandableArray.get(index);
179            if (element.isInSlidingKeyInput()) {
180                return true;
181            }
182        }
183        return false;
184    }
185
186    public synchronized void cancelAllPointerTracker() {
187        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
188        final int arraySize = mArraySize;
189        for (int index = 0; index < arraySize; index++) {
190            final Element element = expandableArray.get(index);
191            element.cancelTracking();
192        }
193    }
194
195    @Override
196    public synchronized String toString() {
197        final StringBuilder sb = new StringBuilder();
198        final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers;
199        final int arraySize = mArraySize;
200        for (int index = 0; index < arraySize; index++) {
201            final Element element = expandableArray.get(index);
202            if (sb.length() > 0)
203                sb.append(" ");
204            sb.append(element.toString());
205        }
206        return "[" + sb.toString() + "]";
207    }
208}
209