Home | History | Annotate | Download | only in latin
      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 
     17 package com.android.inputmethod.latin;
     18 
     19 import android.view.inputmethod.InputMethodManager;
     20 
     21 import android.content.Context;
     22 import android.os.AsyncTask;
     23 import android.text.format.DateUtils;
     24 import android.util.Log;
     25 
     26 public class LatinIMEUtil {
     27 
     28     /**
     29      * Cancel an {@link AsyncTask}.
     30      *
     31      * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
     32      *        task should be interrupted; otherwise, in-progress tasks are allowed
     33      *        to complete.
     34      */
     35     public static void cancelTask(AsyncTask<?, ?, ?> task, boolean mayInterruptIfRunning) {
     36         if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
     37             task.cancel(mayInterruptIfRunning);
     38         }
     39     }
     40 
     41     public static class GCUtils {
     42         private static final String TAG = "GCUtils";
     43         public static final int GC_TRY_COUNT = 2;
     44         // GC_TRY_LOOP_MAX is used for the hard limit of GC wait,
     45         // GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT.
     46         public static final int GC_TRY_LOOP_MAX = 5;
     47         private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS;
     48         private static GCUtils sInstance = new GCUtils();
     49         private int mGCTryCount = 0;
     50 
     51         public static GCUtils getInstance() {
     52             return sInstance;
     53         }
     54 
     55         public void reset() {
     56             mGCTryCount = 0;
     57         }
     58 
     59         public boolean tryGCOrWait(String metaData, Throwable t) {
     60             if (mGCTryCount == 0) {
     61                 System.gc();
     62             }
     63             if (++mGCTryCount > GC_TRY_COUNT) {
     64                 LatinImeLogger.logOnException(metaData, t);
     65                 return false;
     66             } else {
     67                 try {
     68                     Thread.sleep(GC_INTERVAL);
     69                     return true;
     70                 } catch (InterruptedException e) {
     71                     Log.e(TAG, "Sleep was interrupted.");
     72                     LatinImeLogger.logOnException(metaData, t);
     73                     return false;
     74                 }
     75             }
     76         }
     77     }
     78 
     79     public static boolean hasMultipleEnabledIMEs(Context context) {
     80         return ((InputMethodManager) context.getSystemService(
     81                 Context.INPUT_METHOD_SERVICE)).getEnabledInputMethodList().size() > 1;
     82     }
     83 
     84     /* package */ static class RingCharBuffer {
     85         private static RingCharBuffer sRingCharBuffer = new RingCharBuffer();
     86         private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
     87         private static final int INVALID_COORDINATE = -2;
     88         /* package */ static final int BUFSIZE = 20;
     89         private Context mContext;
     90         private boolean mEnabled = false;
     91         private int mEnd = 0;
     92         /* package */ int mLength = 0;
     93         private char[] mCharBuf = new char[BUFSIZE];
     94         private int[] mXBuf = new int[BUFSIZE];
     95         private int[] mYBuf = new int[BUFSIZE];
     96 
     97         private RingCharBuffer() {
     98         }
     99         public static RingCharBuffer getInstance() {
    100             return sRingCharBuffer;
    101         }
    102         public static RingCharBuffer init(Context context, boolean enabled) {
    103             sRingCharBuffer.mContext = context;
    104             sRingCharBuffer.mEnabled = enabled;
    105             return sRingCharBuffer;
    106         }
    107         private int normalize(int in) {
    108             int ret = in % BUFSIZE;
    109             return ret < 0 ? ret + BUFSIZE : ret;
    110         }
    111         public void push(char c, int x, int y) {
    112             if (!mEnabled) return;
    113             mCharBuf[mEnd] = c;
    114             mXBuf[mEnd] = x;
    115             mYBuf[mEnd] = y;
    116             mEnd = normalize(mEnd + 1);
    117             if (mLength < BUFSIZE) {
    118                 ++mLength;
    119             }
    120         }
    121         public char pop() {
    122             if (mLength < 1) {
    123                 return PLACEHOLDER_DELIMITER_CHAR;
    124             } else {
    125                 mEnd = normalize(mEnd - 1);
    126                 --mLength;
    127                 return mCharBuf[mEnd];
    128             }
    129         }
    130         public char getLastChar() {
    131             if (mLength < 1) {
    132                 return PLACEHOLDER_DELIMITER_CHAR;
    133             } else {
    134                 return mCharBuf[normalize(mEnd - 1)];
    135             }
    136         }
    137         public int getPreviousX(char c, int back) {
    138             int index = normalize(mEnd - 2 - back);
    139             if (mLength <= back
    140                     || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
    141                 return INVALID_COORDINATE;
    142             } else {
    143                 return mXBuf[index];
    144             }
    145         }
    146         public int getPreviousY(char c, int back) {
    147             int index = normalize(mEnd - 2 - back);
    148             if (mLength <= back
    149                     || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
    150                 return INVALID_COORDINATE;
    151             } else {
    152                 return mYBuf[index];
    153             }
    154         }
    155         public String getLastString() {
    156             StringBuffer sb = new StringBuffer();
    157             for (int i = 0; i < mLength; ++i) {
    158                 char c = mCharBuf[normalize(mEnd - 1 - i)];
    159                 if (!((LatinIME)mContext).isWordSeparator(c)) {
    160                     sb.append(c);
    161                 } else {
    162                     break;
    163                 }
    164             }
    165             return sb.reverse().toString();
    166         }
    167         public void reset() {
    168             mLength = 0;
    169         }
    170     }
    171 }
    172