15a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka/*
28632bff2d5a8e1160989008dea6eff4b94b065ddTadashi G. Takaoka * Copyright (C) 2010 The Android Open Source Project
35a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka *
45a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); you may not
55a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * use this file except in compliance with the License. You may obtain a copy of
65a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * the License at
75a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka *
85a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0
95a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka *
105a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
115a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
125a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
135a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * License for the specific language governing permissions and limitations under
145a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka * the License.
155a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka */
165a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
1772934bd5967d0127f71fd4d66158b18b4e6ceefeTadashi G. Takaokapackage com.android.inputmethod.keyboard.internal;
1872934bd5967d0127f71fd4d66158b18b4e6ceefeTadashi G. Takaoka
19beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaokaimport android.util.Log;
20beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka
21beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard;
2272934bd5967d0127f71fd4d66158b18b4e6ceefeTadashi G. Takaokaimport com.android.inputmethod.keyboard.PointerTracker;
235a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
2478ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaokaimport java.util.Iterator;
255a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport java.util.LinkedList;
265a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
275a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokapublic class PointerTrackerQueue {
28beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    private static final String TAG = PointerTrackerQueue.class.getSimpleName();
29beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    private static final boolean DEBUG = false;
30beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka
31d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka    private final LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
325a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
33d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka    public synchronized void add(PointerTracker tracker) {
345a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        mQueue.add(tracker);
355a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka    }
365a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
3778ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka    public synchronized void remove(PointerTracker tracker) {
3878ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        mQueue.remove(tracker);
3978ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka    }
4078ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka
41beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    public synchronized void releaseAllPointersOlderThan(PointerTracker tracker,
42beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            long eventTime) {
43beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        if (DEBUG) {
44beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            Log.d(TAG, "releaseAllPoniterOlderThan: [" + tracker.mPointerId + "] " + this);
45beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        }
4678ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        if (!mQueue.contains(tracker)) {
471d7d9664a9850a7c8043651e4b7a055ec034f571Tadashi G. Takaoka            return;
481d7d9664a9850a7c8043651e4b7a055ec034f571Tadashi G. Takaoka        }
4978ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        final Iterator<PointerTracker> it = mQueue.iterator();
5078ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        while (it.hasNext()) {
5178ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            final PointerTracker t = it.next();
5278ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            if (t == tracker) {
5378ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka                break;
5478ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            }
5578ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            if (!t.isModifier()) {
56d3002aa8cd5339d59123e0c96174f6701e2c72ccTadashi G. Takaoka                t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime);
5778ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka                it.remove();
585a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka            }
595a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        }
605a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka    }
615a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
621d7d9664a9850a7c8043651e4b7a055ec034f571Tadashi G. Takaoka    public void releaseAllPointers(long eventTime) {
63d3002aa8cd5339d59123e0c96174f6701e2c72ccTadashi G. Takaoka        releaseAllPointersExcept(null, eventTime);
641d7d9664a9850a7c8043651e4b7a055ec034f571Tadashi G. Takaoka    }
651d7d9664a9850a7c8043651e4b7a055ec034f571Tadashi G. Takaoka
66d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka    public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
67beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        if (DEBUG) {
68beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            if (tracker == null) {
69beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka                Log.d(TAG, "releaseAllPoniters: " + this);
70beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            } else {
71beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka                Log.d(TAG, "releaseAllPoniterExcept: [" + tracker.mPointerId + "] " + this);
72beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            }
73beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        }
7478ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        final Iterator<PointerTracker> it = mQueue.iterator();
7578ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        while (it.hasNext()) {
7678ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            final PointerTracker t = it.next();
7778ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            if (t != tracker) {
7878ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka                t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime);
7978ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka                it.remove();
80d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka            }
81d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka        }
825a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka    }
835a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
84d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka    public synchronized boolean isAnyInSlidingKeyInput() {
85cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka        for (final PointerTracker tracker : mQueue) {
86d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka            if (tracker.isInSlidingKeyInput()) {
87cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka                return true;
88d17786fcd21e53b81e4d4e924adc8becdfa46ec2Tadashi G. Takaoka            }
89cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka        }
90cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka        return false;
91cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka    }
92cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka
93418d80d7de8d24150fc7e1710f7590a33301e546Tadashi G. Takaoka    @Override
94418d80d7de8d24150fc7e1710f7590a33301e546Tadashi G. Takaoka    public String toString() {
9578ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        final StringBuilder sb = new StringBuilder();
9678ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka        for (final PointerTracker tracker : mQueue) {
9778ac86ff9ddfa354567c3146c67c914fc354d3a0Tadashi G. Takaoka            if (sb.length() > 0)
98418d80d7de8d24150fc7e1710f7590a33301e546Tadashi G. Takaoka                sb.append(" ");
99beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka            sb.append("[" + tracker.mPointerId + " "
100beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka                + Keyboard.printableCode(tracker.getKey().mCode) + "]");
101418d80d7de8d24150fc7e1710f7590a33301e546Tadashi G. Takaoka        }
102beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        return sb.toString();
103418d80d7de8d24150fc7e1710f7590a33301e546Tadashi G. Takaoka    }
1045a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka}
105