/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/LatinIMEUtil.java

http://eyes-free.googlecode.com/ · Java · 170 lines · 135 code · 11 blank · 24 comment · 25 complexity · 1b30be2c835bfbfea209d391192dc575 MD5 · raw file

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