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