Home | History | Annotate | Download | only in internal
      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 
     17 package com.android.inputmethod.keyboard.internal;
     18 
     19 import android.util.Log;
     20 
     21 import com.android.inputmethod.latin.CollectionUtils;
     22 
     23 import java.util.ArrayList;
     24 
     25 public 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