aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/Utils.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/Utils.java')
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java150
1 files changed, 136 insertions, 14 deletions
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index e980d3a30..727e3f16d 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -16,13 +16,18 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.keyboard.KeyboardId;
+
+import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
+import android.text.InputType;
import android.text.format.DateUtils;
import android.util.Log;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -41,6 +46,10 @@ public class Utils {
private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4;
private static boolean DBG = LatinImeLogger.sDBG;
+ private Utils() {
+ // Intentional empty constructor for utility class.
+ }
+
/**
* Cancel an {@link AsyncTask}.
*
@@ -55,7 +64,7 @@ public class Utils {
}
public static class GCUtils {
- private static final String TAG = "GCUtils";
+ private static final String GC_TAG = GCUtils.class.getSimpleName();
public static final int GC_TRY_COUNT = 2;
// GC_TRY_LOOP_MAX is used for the hard limit of GC wait,
// GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT.
@@ -84,7 +93,7 @@ public class Utils {
Thread.sleep(GC_INTERVAL);
return true;
} catch (InterruptedException e) {
- Log.e(TAG, "Sleep was interrupted.");
+ Log.e(GC_TAG, "Sleep was interrupted.");
LatinImeLogger.logOnException(metaData, t);
return false;
}
@@ -261,6 +270,19 @@ public class Utils {
return dp[sl][tl];
}
+ // Get the current stack trace
+ public static String getStackTrace() {
+ StringBuilder sb = new StringBuilder();
+ try {
+ throw new RuntimeException();
+ } catch (RuntimeException e) {
+ StackTraceElement[] frames = e.getStackTrace();
+ // Start at 1 because the first frame is here and we don't care about it
+ for (int j = 1; j < frames.length; ++j) sb.append(frames[j].toString() + "\n");
+ }
+ return sb.toString();
+ }
+
// In dictionary.cpp, getSuggestion() method,
// suggestion scores are computed using the below formula.
// original score (called 'frequency')
@@ -268,13 +290,22 @@ public class Utils {
// (the number of matched characters between typed word and suggested word))
// * (individual word's score which defined in the unigram dictionary,
// and this score is defined in range [0, 255].)
- // * (when before.length() == after.length(),
- // mFullWordMultiplier (this is defined 2))
- // So, maximum original score is pow(2, before.length()) * 255 * 2
- // So, we can normalize original score by dividing this value.
+ // Then, the following processing is applied.
+ // - If the dictionary word is matched up to the point of the user entry
+ // (full match up to min(before.length(), after.length())
+ // => Then multiply by FULL_MATCHED_WORDS_PROMOTION_RATE (this is defined 1.2)
+ // - If the word is a true full match except for differences in accents or
+ // capitalization, then treat it as if the frequency was 255.
+ // - If before.length() == after.length()
+ // => multiply by mFullWordMultiplier (this is defined 2))
+ // So, maximum original score is pow(2, min(before.length(), after.length())) * 255 * 2 * 1.2
+ // For historical reasons we ignore the 1.2 modifier (because the measure for a good
+ // autocorrection threshold was done at a time when it didn't exist). This doesn't change
+ // the result.
+ // So, we can normalize original score by dividing pow(2, min(b.l(),a.l())) * 255 * 2.
private static final int MAX_INITIAL_SCORE = 255;
private static final int TYPED_LETTER_MULTIPLIER = 2;
- private static final int FULL_WORD_MULTIPLYER = 2;
+ private static final int FULL_WORD_MULTIPLIER = 2;
public static double calcNormalizedScore(CharSequence before, CharSequence after, int score) {
final int beforeLength = before.length();
final int afterLength = after.length();
@@ -284,7 +315,7 @@ public class Utils {
// correction.
final double maximumScore = MAX_INITIAL_SCORE
* Math.pow(TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength))
- * FULL_WORD_MULTIPLYER;
+ * FULL_WORD_MULTIPLIER;
// add a weight based on edit distance.
// distance <= max(afterLength, beforeLength) == afterLength,
// so, 0 <= distance / afterLength <= 1
@@ -293,7 +324,7 @@ public class Utils {
}
public static class UsabilityStudyLogUtils {
- private static final String TAG = "UsabilityStudyLogUtils";
+ private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName();
private static final String FILENAME = "log.txt";
private static final UsabilityStudyLogUtils sInstance =
new UsabilityStudyLogUtils();
@@ -330,7 +361,7 @@ public class Utils {
try {
mWriter = getPrintWriter(mDirectory, FILENAME, false);
} catch (IOException e) {
- Log.e(TAG, "Can't create log file.");
+ Log.e(USABILITY_TAG, "Can't create log file.");
}
}
}
@@ -367,7 +398,7 @@ public class Utils {
final String printString = String.format("%s\t%d\t%s\n",
mDateFormat.format(mDate), currentTime, log);
if (LatinImeLogger.sDBG) {
- Log.d(TAG, "Write: " + log);
+ Log.d(USABILITY_TAG, "Write: " + log);
}
mWriter.print(printString);
}
@@ -388,10 +419,10 @@ public class Utils {
sb.append(line);
}
} catch (IOException e) {
- Log.e(TAG, "Can't read log file.");
+ Log.e(USABILITY_TAG, "Can't read log file.");
} finally {
if (LatinImeLogger.sDBG) {
- Log.d(TAG, "output all logs\n" + sb.toString());
+ Log.d(USABILITY_TAG, "output all logs\n" + sb.toString());
}
mIms.getCurrentInputConnection().commitText(sb.toString(), 0);
try {
@@ -410,7 +441,7 @@ public class Utils {
public void run() {
if (mFile != null && mFile.exists()) {
if (LatinImeLogger.sDBG) {
- Log.d(TAG, "Delete log file.");
+ Log.d(USABILITY_TAG, "Delete log file.");
}
mFile.delete();
mWriter.close();
@@ -439,4 +470,95 @@ public class Utils {
return new PrintWriter(new FileOutputStream(mFile), true /* autoFlush */);
}
}
+
+ public static int getKeyboardMode(EditorInfo attribute) {
+ if (attribute == null)
+ return KeyboardId.MODE_TEXT;
+
+ final int inputType = attribute.inputType;
+ final int variation = inputType & InputType.TYPE_MASK_VARIATION;
+
+ switch (inputType & InputType.TYPE_MASK_CLASS) {
+ case InputType.TYPE_CLASS_NUMBER:
+ case InputType.TYPE_CLASS_DATETIME:
+ return KeyboardId.MODE_NUMBER;
+ case InputType.TYPE_CLASS_PHONE:
+ return KeyboardId.MODE_PHONE;
+ case InputType.TYPE_CLASS_TEXT:
+ if (Utils.isEmailVariation(variation)) {
+ return KeyboardId.MODE_EMAIL;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
+ return KeyboardId.MODE_URL;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
+ return KeyboardId.MODE_IM;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
+ return KeyboardId.MODE_TEXT;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
+ return KeyboardId.MODE_WEB;
+ } else {
+ return KeyboardId.MODE_TEXT;
+ }
+ default:
+ return KeyboardId.MODE_TEXT;
+ }
+ }
+
+ public static boolean isEmailVariation(int variation) {
+ return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
+ || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
+ }
+
+ // Please refer to TextView.isPasswordInputType
+ public static boolean isPasswordInputType(int inputType) {
+ final int variation =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return (variation
+ == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD))
+ || (variation
+ == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD))
+ || (variation
+ == (InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD));
+ }
+
+ // Please refer to TextView.isVisiblePasswordInputType
+ public static boolean isVisiblePasswordInputType(int inputType) {
+ final int variation =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return variation
+ == (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
+ }
+
+ public static boolean containsInCsv(String key, String csv) {
+ if (csv == null)
+ return false;
+ for (String option : csv.split(",")) {
+ if (option.equals(key))
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean inPrivateImeOptions(String packageName, String key,
+ EditorInfo attribute) {
+ if (attribute == null)
+ return false;
+ return containsInCsv(packageName != null ? packageName + "." + key : key,
+ attribute.privateImeOptions);
+ }
+
+ /**
+ * Returns a main dictionary resource id
+ * @return main dictionary resource id
+ */
+ public static int getMainDictionaryResourceId(Resources res) {
+ return res.getIdentifier("main", "raw", LatinIME.class.getPackage().getName());
+ }
+
+ public static void loadNativeLibrary() {
+ try {
+ System.loadLibrary("jni_latinime");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.e(TAG, "Could not load native library jni_latinime");
+ }
+ }
}