aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/compat
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/compat')
-rw-r--r--java/src/com/android/inputmethod/compat/BuildCompatUtils.java7
-rw-r--r--java/src/com/android/inputmethod/compat/CharacterCompat.java47
-rw-r--r--java/src/com/android/inputmethod/compat/CompatUtils.java2
-rw-r--r--java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java188
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java11
-rw-r--r--java/src/com/android/inputmethod/compat/LocaleSpanCompatUtils.java26
-rw-r--r--java/src/com/android/inputmethod/compat/NotificationCompatUtils.java6
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java36
-rw-r--r--java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java57
-rw-r--r--java/src/com/android/inputmethod/compat/ViewCompatUtils.java7
-rw-r--r--java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java43
-rw-r--r--java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java72
12 files changed, 323 insertions, 179 deletions
diff --git a/java/src/com/android/inputmethod/compat/BuildCompatUtils.java b/java/src/com/android/inputmethod/compat/BuildCompatUtils.java
index 7d1717bd1..5d56f12ae 100644
--- a/java/src/com/android/inputmethod/compat/BuildCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/BuildCompatUtils.java
@@ -33,11 +33,4 @@ public final class BuildCompatUtils {
public static final int EFFECTIVE_SDK_INT = IS_RELEASE_BUILD
? Build.VERSION.SDK_INT
: Build.VERSION.SDK_INT + 1;
-
- /**
- * API version for L-release.
- */
- // TODO: Substitute this constant reference with Build.VERSION_CODES.L* once the *next* version
- // becomes available.
- public static final int VERSION_CODES_LXX = 21;
}
diff --git a/java/src/com/android/inputmethod/compat/CharacterCompat.java b/java/src/com/android/inputmethod/compat/CharacterCompat.java
new file mode 100644
index 000000000..609fe1638
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/CharacterCompat.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.compat;
+
+import java.lang.reflect.Method;
+
+public final class CharacterCompat {
+ // Note that Character.isAlphabetic(int), has been introduced in API level 19
+ // (Build.VERSION_CODE.KITKAT).
+ private static final Method METHOD_isAlphabetic = CompatUtils.getMethod(
+ Character.class, "isAlphabetic", int.class);
+
+ private CharacterCompat() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public static boolean isAlphabetic(final int code) {
+ if (METHOD_isAlphabetic != null) {
+ return (Boolean)CompatUtils.invoke(null, false, METHOD_isAlphabetic, code);
+ }
+ switch (Character.getType(code)) {
+ case Character.UPPERCASE_LETTER:
+ case Character.LOWERCASE_LETTER:
+ case Character.TITLECASE_LETTER:
+ case Character.MODIFIER_LETTER:
+ case Character.OTHER_LETTER:
+ case Character.LETTER_NUMBER:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java
index 6aa2736c1..5db80190c 100644
--- a/java/src/com/android/inputmethod/compat/CompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/CompatUtils.java
@@ -144,7 +144,7 @@ public final class CompatUtils {
public <T> ToObjectMethodWrapper<T> getMethod(final String name,
final T defaultValue, final Class<?>... parameterTypes) {
- return new ToObjectMethodWrapper<T>(CompatUtils.getMethod(mClass, name, parameterTypes),
+ return new ToObjectMethodWrapper<>(CompatUtils.getMethod(mClass, name, parameterTypes),
defaultValue);
}
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
index 5af31795c..01a9e6712 100644
--- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
@@ -16,13 +16,20 @@
package com.android.inputmethod.compat;
+import android.annotation.TargetApi;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.os.Build;
+import android.view.inputmethod.CursorAnchorInfo;
-import com.android.inputmethod.annotations.UsedForTesting;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
-@UsedForTesting
-public final class CursorAnchorInfoCompatWrapper {
+/**
+ * A wrapper for {@link CursorAnchorInfo}, which has been introduced in API Level 21. You can use
+ * this wrapper to avoid direct dependency on newly introduced types.
+ */
+public class CursorAnchorInfoCompatWrapper {
/**
* The insertion marker or character bounds have at least one visible region.
@@ -39,123 +46,140 @@ public final class CursorAnchorInfoCompatWrapper {
*/
public static final int FLAG_IS_RTL = 0x04;
- // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
- private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
- private static final CompatUtils.ToIntMethodWrapper sGetSelectionStartMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetSelectionEndMethod;
- private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterBoundsMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetCharacterBoundsFlagsMethod;
- private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBottomMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod;
- private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod;
-
- private static int INVALID_TEXT_INDEX = -1;
- static {
- sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
- "android.view.inputmethod.CursorAnchorInfo");
- sGetSelectionStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getSelectionStart", INVALID_TEXT_INDEX);
- sGetSelectionEndMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getSelectionEnd", INVALID_TEXT_INDEX);
- sGetCharacterBoundsMethod = sCursorAnchorInfoClass.getMethod(
- "getCharacterBounds", (RectF)null, int.class);
- sGetCharacterBoundsFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getCharacterBoundsFlags", 0, int.class);
- sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
- "getComposingText", (CharSequence)null);
- sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getComposingTextStart", INVALID_TEXT_INDEX);
- sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerBaseline", 0.0f);
- sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerBottom", 0.0f);
- sGetInsertionMarkerHorizontalMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerHorizontal", 0.0f);
- sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerTop", 0.0f);
- sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null);
- sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerFlags", 0);
- }
-
- @UsedForTesting
- public boolean isAvailable() {
- return sCursorAnchorInfoClass.exists() && mInstance != null;
- }
-
- private Object mInstance;
-
- private CursorAnchorInfoCompatWrapper(final Object instance) {
- mInstance = instance;
+ CursorAnchorInfoCompatWrapper() {
+ // This class is not publicly instantiable.
}
- @UsedForTesting
- public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
- if (!sCursorAnchorInfoClass.exists()) {
- return new CursorAnchorInfoCompatWrapper(null);
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ @Nullable
+ public static CursorAnchorInfoCompatWrapper wrap(@Nullable final CursorAnchorInfo instance) {
+ if (BuildCompatUtils.EFFECTIVE_SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ return null;
}
- return new CursorAnchorInfoCompatWrapper(instance);
- }
-
- private static final class FakeHolder {
- static CursorAnchorInfoCompatWrapper sInstance = new CursorAnchorInfoCompatWrapper(null);
- }
-
- @UsedForTesting
- public static CursorAnchorInfoCompatWrapper getFake() {
- return FakeHolder.sInstance;
+ if (instance == null) {
+ return null;
+ }
+ return new RealWrapper(instance);
}
public int getSelectionStart() {
- return sGetSelectionStartMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getSelectionEnd() {
- return sGetSelectionEndMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public CharSequence getComposingText() {
- return sGetComposingTextMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getComposingTextStart() {
- return sGetComposingTextStartMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public Matrix getMatrix() {
- return sGetMatrixMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
+ @SuppressWarnings("unused")
public RectF getCharacterBounds(final int index) {
- return sGetCharacterBoundsMethod.invoke(mInstance, index);
+ throw new UnsupportedOperationException("not supported.");
}
+ @SuppressWarnings("unused")
public int getCharacterBoundsFlags(final int index) {
- return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerBaseline() {
- return sGetInsertionMarkerBaselineMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerBottom() {
- return sGetInsertionMarkerBottomMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerHorizontal() {
- return sGetInsertionMarkerHorizontalMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerTop() {
- return sGetInsertionMarkerTopMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getInsertionMarkerFlags() {
- return sGetInsertionMarkerFlagsMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private static final class RealWrapper extends CursorAnchorInfoCompatWrapper {
+
+ @Nonnull
+ private final CursorAnchorInfo mInstance;
+
+ public RealWrapper(@Nonnull final CursorAnchorInfo info) {
+ mInstance = info;
+ }
+
+ @Override
+ public int getSelectionStart() {
+ return mInstance.getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd() {
+ return mInstance.getSelectionEnd();
+ }
+
+ @Override
+ public CharSequence getComposingText() {
+ return mInstance.getComposingText();
+ }
+
+ @Override
+ public int getComposingTextStart() {
+ return mInstance.getComposingTextStart();
+ }
+
+ @Override
+ public Matrix getMatrix() {
+ return mInstance.getMatrix();
+ }
+
+ @Override
+ public RectF getCharacterBounds(final int index) {
+ return mInstance.getCharacterBounds(index);
+ }
+
+ @Override
+ public int getCharacterBoundsFlags(final int index) {
+ return mInstance.getCharacterBoundsFlags(index);
+ }
+
+ @Override
+ public float getInsertionMarkerBaseline() {
+ return mInstance.getInsertionMarkerBaseline();
+ }
+
+ @Override
+ public float getInsertionMarkerBottom() {
+ return mInstance.getInsertionMarkerBottom();
+ }
+
+ @Override
+ public float getInsertionMarkerHorizontal() {
+ return mInstance.getInsertionMarkerHorizontal();
+ }
+
+ @Override
+ public float getInsertionMarkerTop() {
+ return mInstance.getInsertionMarkerTop();
+ }
+
+ @Override
+ public int getInsertionMarkerFlags() {
+ return mInstance.getInsertionMarkerFlags();
+ }
}
}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
index 365867257..58ad4bd4c 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatUtils.java
@@ -20,11 +20,14 @@ import android.os.Build;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.RichInputMethodSubtype;
+import com.android.inputmethod.latin.common.Constants;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import javax.annotation.Nonnull;
+
public final class InputMethodSubtypeCompatUtils {
private static final String TAG = InputMethodSubtypeCompatUtils.class.getSimpleName();
// Note that InputMethodSubtype(int nameId, int iconId, String locale, String mode,
@@ -51,6 +54,8 @@ public final class InputMethodSubtypeCompatUtils {
// This utility class is not publicly instantiable.
}
+ @SuppressWarnings("deprecation")
+ @Nonnull
public static InputMethodSubtype newInputMethodSubtype(int nameId, int iconId, String locale,
String mode, String extraValue, boolean isAuxiliary,
boolean overridesImplicitlyEnabledSubtype, int id) {
@@ -64,6 +69,10 @@ public final class InputMethodSubtypeCompatUtils {
overridesImplicitlyEnabledSubtype, id);
}
+ public static boolean isAsciiCapable(final RichInputMethodSubtype subtype) {
+ return isAsciiCapable(subtype.getRawSubtype());
+ }
+
public static boolean isAsciiCapable(final InputMethodSubtype subtype) {
return isAsciiCapableWithAPI(subtype)
|| subtype.containsExtraValueKey(Constants.Subtype.ExtraValue.ASCII_CAPABLE);
diff --git a/java/src/com/android/inputmethod/compat/LocaleSpanCompatUtils.java b/java/src/com/android/inputmethod/compat/LocaleSpanCompatUtils.java
index f411f181b..58e5a36b6 100644
--- a/java/src/com/android/inputmethod/compat/LocaleSpanCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/LocaleSpanCompatUtils.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.compat;
import android.text.Spannable;
+import android.text.Spanned;
import android.text.style.LocaleSpan;
import android.util.Log;
@@ -127,13 +128,13 @@ public final class LocaleSpanCompatUtils {
final int spanFlag = spannable.getSpanFlags(existingLocaleSpan);
if (spanStart < newStart) {
newStart = spanStart;
- isStartExclusive = ((spanFlag & Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) ==
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ isStartExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (newEnd < spanEnd) {
newEnd = spanEnd;
- isEndExclusive = ((spanFlag & Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) ==
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ isEndExclusive = ((spanFlag & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
existingLocaleSpansToBeMerged.add(existingLocaleSpan);
}
@@ -201,24 +202,17 @@ public final class LocaleSpanCompatUtils {
private static int getSpanFlag(final int originalFlag,
final boolean isStartExclusive, final boolean isEndExclusive) {
- return (originalFlag & ~Spannable.SPAN_POINT_MARK_MASK) |
+ return (originalFlag & ~Spanned.SPAN_POINT_MARK_MASK) |
getSpanPointMarkFlag(isStartExclusive, isEndExclusive);
}
private static int getSpanPointMarkFlag(final boolean isStartExclusive,
final boolean isEndExclusive) {
if (isStartExclusive) {
- if (isEndExclusive) {
- return Spannable.SPAN_EXCLUSIVE_EXCLUSIVE;
- } else {
- return Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
- }
- } else {
- if (isEndExclusive) {
- return Spannable.SPAN_INCLUSIVE_EXCLUSIVE;
- } else {
- return Spannable.SPAN_INCLUSIVE_INCLUSIVE;
- }
+ return isEndExclusive ? Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ : Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
}
+ return isEndExclusive ? Spanned.SPAN_INCLUSIVE_EXCLUSIVE
+ : Spanned.SPAN_INCLUSIVE_INCLUSIVE;
}
}
diff --git a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java
index eb180071e..70ab972c5 100644
--- a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java
@@ -71,13 +71,13 @@ public class NotificationCompatUtils {
CompatUtils.invoke(builder, null, METHOD_setPriority, PRIORITY_LOW);
}
+ @SuppressWarnings("deprecation")
public static Notification build(final Notification.Builder builder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// #build was added in API level 16, JELLY_BEAN
return (Notification) CompatUtils.invoke(builder, null, METHOD_build);
- } else {
- // #getNotification was deprecated in API level 16, JELLY_BEAN
- return builder.getNotification();
}
+ // #getNotification was deprecated in API level 16, JELLY_BEAN
+ return builder.getNotification();
}
}
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index c33c01552..4d2925d30 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -23,13 +23,17 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.LocaleUtils;
import com.android.inputmethod.latin.define.DebugFlags;
-import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Locale;
+
+import javax.annotation.Nullable;
public final class SuggestionSpanUtils {
// Note that SuggestionSpan.FLAG_AUTO_CORRECTION has been introduced
@@ -51,20 +55,22 @@ public final class SuggestionSpanUtils {
// This utility class is not publicly instantiable.
}
+ @UsedForTesting
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
final Context context, final String text) {
if (TextUtils.isEmpty(text) || OBJ_FLAG_AUTO_CORRECTION == null) {
return text;
}
final Spannable spannable = new SpannableString(text);
+ // TODO: Set locale if it is feasible.
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
- new String[] {} /* suggestions */, OBJ_FLAG_AUTO_CORRECTION,
- SuggestionSpanPickedNotificationReceiver.class);
+ new String[] {} /* suggestions */, OBJ_FLAG_AUTO_CORRECTION, null);
spannable.setSpan(suggestionSpan, 0, text.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
return spannable;
}
+ @UsedForTesting
public static CharSequence getTextWithSuggestionSpan(final Context context,
final String pickedWord, final SuggestedWords suggestedWords) {
if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty()
@@ -86,11 +92,31 @@ public final class SuggestionSpanUtils {
suggestionsList.add(word.toString());
}
}
+ // TODO: Set locale if it is feasible.
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
- suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */,
- SuggestionSpanPickedNotificationReceiver.class);
+ suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */, null);
final Spannable spannable = new SpannableString(pickedWord);
spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}
+
+ /**
+ * Returns first {@link Locale} found in the given array of {@link SuggestionSpan}.
+ * @param suggestionSpans the array of {@link SuggestionSpan} to be examined.
+ * @return the first {@link Locale} found in {@code suggestionSpans}. {@code null} when not
+ * found.
+ */
+ @UsedForTesting
+ @Nullable
+ public static Locale findFirstLocaleFromSuggestionSpans(
+ final SuggestionSpan[] suggestionSpans) {
+ for (final SuggestionSpan suggestionSpan : suggestionSpans) {
+ final String localeString = suggestionSpan.getLocale();
+ if (TextUtils.isEmpty(localeString)) {
+ continue;
+ }
+ return LocaleUtils.constructLocaleFromString(localeString);
+ }
+ return null;
+ }
}
diff --git a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java b/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java
deleted file mode 100644
index 1fb597ba6..000000000
--- a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.compat;
-
-import android.content.Context;
-import android.provider.UserDictionary.Words;
-
-import java.lang.reflect.Method;
-import java.util.Locale;
-
-public final class UserDictionaryCompatUtils {
- // UserDictionary.Words#addWord(Context, String, int, String, Locale) was introduced
- // in API level 16 (Build.VERSION_CODES.JELLY_BEAN).
- private static final Method METHOD_addWord = CompatUtils.getMethod(Words.class, "addWord",
- Context.class, String.class, int.class, String.class, Locale.class);
-
- @SuppressWarnings("deprecation")
- public static void addWord(final Context context, final String word,
- final int freq, final String shortcut, final Locale locale) {
- if (hasNewerAddWord()) {
- CompatUtils.invoke(Words.class, null, METHOD_addWord, context, word, freq, shortcut,
- locale);
- } else {
- // Fall back to the pre-JellyBean method.
- final int localeType;
- if (null == locale) {
- localeType = Words.LOCALE_TYPE_ALL;
- } else {
- final Locale currentLocale = context.getResources().getConfiguration().locale;
- if (locale.equals(currentLocale)) {
- localeType = Words.LOCALE_TYPE_CURRENT;
- } else {
- localeType = Words.LOCALE_TYPE_ALL;
- }
- }
- Words.addWord(context, word, freq, localeType);
- }
- }
-
- public static final boolean hasNewerAddWord() {
- return null != METHOD_addWord;
- }
-}
diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
index 0f00be133..16260ab6a 100644
--- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
@@ -31,9 +31,6 @@ public final class ViewCompatUtils {
private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod(
View.class, "setPaddingRelative",
int.class, int.class, int.class, int.class);
- // Note that View.setElevation(float) has been introduced in API level 21.
- private static final Method METHOD_setElevation = CompatUtils.getMethod(
- View.class, "setElevation", float.class);
// Note that View.setTextAlignment(int) has been introduced in API level 17.
private static final Method METHOD_setTextAlignment = CompatUtils.getMethod(
View.class, "setTextAlignment", int.class);
@@ -58,10 +55,6 @@ public final class ViewCompatUtils {
CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom);
}
- public static void setElevation(final View view, final float elevation) {
- CompatUtils.invoke(view, null, METHOD_setElevation, elevation);
- }
-
// These TEXT_ALIGNMENT_* constants have been introduced in API 17.
public static final int TEXT_ALIGNMENT_INHERIT = 0;
public static final int TEXT_ALIGNMENT_GRAVITY = 1;
diff --git a/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java
new file mode 100644
index 000000000..0c8e5b77d
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.compat;
+
+import android.inputmethodservice.InputMethodService;
+import android.os.Build;
+import android.view.View;
+
+public class ViewOutlineProviderCompatUtils {
+ private ViewOutlineProviderCompatUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public interface InsetsUpdater {
+ public void setInsets(final InputMethodService.Insets insets);
+ }
+
+ private static final InsetsUpdater EMPTY_INSETS_UPDATER = new InsetsUpdater() {
+ @Override
+ public void setInsets(final InputMethodService.Insets insets) {}
+ };
+
+ public static InsetsUpdater setInsetsOutlineProvider(final View view) {
+ if (BuildCompatUtils.EFFECTIVE_SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ return EMPTY_INSETS_UPDATER;
+ }
+ return ViewOutlineProviderCompatUtilsLXX.setInsetsOutlineProvider(view);
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java
new file mode 100644
index 000000000..5bbb5ce99
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.compat;
+
+import android.annotation.TargetApi;
+import android.graphics.Outline;
+import android.inputmethodservice.InputMethodService;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+class ViewOutlineProviderCompatUtilsLXX {
+ private ViewOutlineProviderCompatUtilsLXX() {
+ // This utility class is not publicly instantiable.
+ }
+
+ static InsetsUpdater setInsetsOutlineProvider(final View view) {
+ final InsetsOutlineProvider provider = new InsetsOutlineProvider(view);
+ view.setOutlineProvider(provider);
+ return provider;
+ }
+
+ private static class InsetsOutlineProvider extends ViewOutlineProvider
+ implements InsetsUpdater {
+ private final View mView;
+ private static final int NO_DATA = -1;
+ private int mLastVisibleTopInsets = NO_DATA;
+
+ public InsetsOutlineProvider(final View view) {
+ mView = view;
+ view.setOutlineProvider(this);
+ }
+
+ @Override
+ public void setInsets(final InputMethodService.Insets insets) {
+ final int visibleTopInsets = insets.visibleTopInsets;
+ if (mLastVisibleTopInsets != visibleTopInsets) {
+ mLastVisibleTopInsets = visibleTopInsets;
+ mView.invalidateOutline();
+ }
+ }
+
+ @Override
+ public void getOutline(final View view, final Outline outline) {
+ if (mLastVisibleTopInsets == NO_DATA) {
+ // Call default implementation.
+ ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
+ return;
+ }
+ // TODO: Revisit this when floating/resize keyboard is supported.
+ outline.setRect(
+ view.getLeft(), mLastVisibleTopInsets, view.getRight(), view.getBottom());
+ }
+ }
+}