diff options
Diffstat (limited to 'java/src/com/android/inputmethod/compat')
7 files changed, 297 insertions, 186 deletions
diff --git a/java/src/com/android/inputmethod/compat/AppWorkaroundsHelper.java b/java/src/com/android/inputmethod/compat/AppWorkaroundsHelper.java deleted file mode 100644 index 21535e421..000000000 --- a/java/src/com/android/inputmethod/compat/AppWorkaroundsHelper.java +++ /dev/null @@ -1,29 +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.pm.PackageInfo; - -public class AppWorkaroundsHelper { - private AppWorkaroundsHelper() { - // This helper class is not publicly instantiable. - } - - public static boolean evaluateIsBrokenByRecorrection(final PackageInfo info) { - return false; - } -} diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java index 4fd2a6936..6aa2736c1 100644 --- a/java/src/com/android/inputmethod/compat/CompatUtils.java +++ b/java/src/com/android/inputmethod/compat/CompatUtils.java @@ -127,4 +127,92 @@ public final class CompatUtils { Log.e(TAG, "Exception in setFieldValue", e); } } + + public static ClassWrapper getClassWrapper(final String className) { + return new ClassWrapper(getClass(className)); + } + + public static final class ClassWrapper { + private final Class<?> mClass; + public ClassWrapper(final Class<?> targetClass) { + mClass = targetClass; + } + + public boolean exists() { + return mClass != null; + } + + public <T> ToObjectMethodWrapper<T> getMethod(final String name, + final T defaultValue, final Class<?>... parameterTypes) { + return new ToObjectMethodWrapper<T>(CompatUtils.getMethod(mClass, name, parameterTypes), + defaultValue); + } + + public ToIntMethodWrapper getPrimitiveMethod(final String name, final int defaultValue, + final Class<?>... parameterTypes) { + return new ToIntMethodWrapper(CompatUtils.getMethod(mClass, name, parameterTypes), + defaultValue); + } + + public ToFloatMethodWrapper getPrimitiveMethod(final String name, final float defaultValue, + final Class<?>... parameterTypes) { + return new ToFloatMethodWrapper(CompatUtils.getMethod(mClass, name, parameterTypes), + defaultValue); + } + + public ToBooleanMethodWrapper getPrimitiveMethod(final String name, + final boolean defaultValue, final Class<?>... parameterTypes) { + return new ToBooleanMethodWrapper(CompatUtils.getMethod(mClass, name, parameterTypes), + defaultValue); + } + } + + public static final class ToObjectMethodWrapper<T> { + private final Method mMethod; + private final T mDefaultValue; + public ToObjectMethodWrapper(final Method method, final T defaultValue) { + mMethod = method; + mDefaultValue = defaultValue; + } + @SuppressWarnings("unchecked") + public T invoke(final Object receiver, final Object... args) { + return (T) CompatUtils.invoke(receiver, mDefaultValue, mMethod, args); + } + } + + public static final class ToIntMethodWrapper { + private final Method mMethod; + private final int mDefaultValue; + public ToIntMethodWrapper(final Method method, final int defaultValue) { + mMethod = method; + mDefaultValue = defaultValue; + } + public int invoke(final Object receiver, final Object... args) { + return (int) CompatUtils.invoke(receiver, mDefaultValue, mMethod, args); + } + } + + public static final class ToFloatMethodWrapper { + private final Method mMethod; + private final float mDefaultValue; + public ToFloatMethodWrapper(final Method method, final float defaultValue) { + mMethod = method; + mDefaultValue = defaultValue; + } + public float invoke(final Object receiver, final Object... args) { + return (float) CompatUtils.invoke(receiver, mDefaultValue, mMethod, args); + } + } + + public static final class ToBooleanMethodWrapper { + private final Method mMethod; + private final boolean mDefaultValue; + public ToBooleanMethodWrapper(final Method method, final boolean defaultValue) { + mMethod = method; + mDefaultValue = defaultValue; + } + public boolean invoke(final Object receiver, final Object... args) { + return (boolean) CompatUtils.invoke(receiver, mDefaultValue, mMethod, args); + } + } } diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java index 2cec14240..5af31795c 100644 --- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java @@ -21,67 +21,72 @@ import android.graphics.RectF; import com.android.inputmethod.annotations.UsedForTesting; -import java.lang.reflect.Method; - @UsedForTesting public final class CursorAnchorInfoCompatWrapper { - // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX). - private static Class<?> getCursorAnchorInfoClass() { - try { - return Class.forName("android.view.inputmethod.CursorAnchorInfo"); - } catch (ClassNotFoundException e) { - return null; - } - } - private static final Class<?> CLASS; - private static final Method METHOD_GET_CHARACTER_RECT; - private static final Method METHOD_GET_CHARACTER_RECT_FLAGS; - private static final Method METHOD_GET_COMPOSING_TEXT; - private static final Method METHOD_GET_COMPOSING_TEXT_START; - private static final Method METHOD_GET_MATRIX; - static { - CLASS = getCursorAnchorInfoClass(); - METHOD_GET_CHARACTER_RECT = CompatUtils.getMethod(CLASS, "getCharacterRect", int.class); - METHOD_GET_CHARACTER_RECT_FLAGS = CompatUtils.getMethod(CLASS, "getCharacterRectFlags", - int.class); - METHOD_GET_COMPOSING_TEXT = CompatUtils.getMethod(CLASS, "getComposingText"); - METHOD_GET_COMPOSING_TEXT_START = CompatUtils.getMethod(CLASS, "getComposingTextStart"); - METHOD_GET_MATRIX = CompatUtils.getMethod(CLASS, "getMatrix"); - } - - @UsedForTesting - public static boolean isAvailable() { - return CLASS != null; - } - - public static final int CHARACTER_RECT_TYPE_MASK = 0x0f; /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor did not specify any type of this - * character. Editor authors should not use this flag. + * The insertion marker or character bounds have at least one visible region. */ - public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; + public static final int FLAG_HAS_VISIBLE_REGION = 0x01; /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely visible. + * The insertion marker or character bounds have at least one invisible (clipped) region. */ - public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; + public static final int FLAG_HAS_INVISIBLE_REGION = 0x02; /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: some area of the character is invisible. + * The insertion marker or character bounds is placed at right-to-left (RTL) character. */ - public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; + public static final int FLAG_IS_RTL = 0x04; - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible. - */ - public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; + // 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); + } - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor gave up to calculate the rectangle - * for this character. Input method authors should ignore the returned rectangle. - */ - public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; + @UsedForTesting + public boolean isAvailable() { + return sCursorAnchorInfoClass.exists() && mInstance != null; + } private Object mInstance; @@ -91,7 +96,7 @@ public final class CursorAnchorInfoCompatWrapper { @UsedForTesting public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) { - if (!isAvailable()) { + if (!sCursorAnchorInfoClass.exists()) { return new CursorAnchorInfoCompatWrapper(null); } return new CursorAnchorInfoCompatWrapper(instance); @@ -106,30 +111,51 @@ public final class CursorAnchorInfoCompatWrapper { return FakeHolder.sInstance; } + public int getSelectionStart() { + return sGetSelectionStartMethod.invoke(mInstance); + } + + public int getSelectionEnd() { + return sGetSelectionEndMethod.invoke(mInstance); + } + public CharSequence getComposingText() { - return (CharSequence) CompatUtils.invoke(mInstance, null, METHOD_GET_COMPOSING_TEXT); + return sGetComposingTextMethod.invoke(mInstance); } - private static int COMPOSING_TEXT_START_DEFAULT = -1; public int getComposingTextStart() { - if (mInstance == null || METHOD_GET_COMPOSING_TEXT_START == null) { - return COMPOSING_TEXT_START_DEFAULT; - } - return (int) CompatUtils.invoke(mInstance, null, METHOD_GET_COMPOSING_TEXT_START); + return sGetComposingTextStartMethod.invoke(mInstance); } public Matrix getMatrix() { - return (Matrix) CompatUtils.invoke(mInstance, null, METHOD_GET_MATRIX); + return sGetMatrixMethod.invoke(mInstance); } - public RectF getCharacterRect(final int index) { - return (RectF) CompatUtils.invoke(mInstance, null, METHOD_GET_CHARACTER_RECT, index); + public RectF getCharacterBounds(final int index) { + return sGetCharacterBoundsMethod.invoke(mInstance, index); } - public int getCharacterRectFlags(final int index) { - if (mInstance == null || METHOD_GET_CHARACTER_RECT_FLAGS == null) { - return CHARACTER_RECT_TYPE_UNSPECIFIED; - } - return (int) CompatUtils.invoke(mInstance, null, METHOD_GET_CHARACTER_RECT_FLAGS, index); + public int getCharacterBoundsFlags(final int index) { + return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index); + } + + public float getInsertionMarkerBaseline() { + return sGetInsertionMarkerBaselineMethod.invoke(mInstance); + } + + public float getInsertionMarkerBottom() { + return sGetInsertionMarkerBottomMethod.invoke(mInstance); + } + + public float getInsertionMarkerHorizontal() { + return sGetInsertionMarkerHorizontalMethod.invoke(mInstance); + } + + public float getInsertionMarkerTop() { + return sGetInsertionMarkerTopMethod.invoke(mInstance); + } + + public int getInsertionMarkerFlags() { + return sGetInsertionMarkerFlagsMethod.invoke(mInstance); } } diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java index be7bf402d..a5c71b22f 100644 --- a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java @@ -16,67 +16,34 @@ package com.android.inputmethod.compat; -import android.util.Log; import android.view.inputmethod.InputConnection; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; +import android.view.inputmethod.InputMethodManager; public final class InputConnectionCompatUtils { - private static final String TAG = InputConnectionCompatUtils.class.getSimpleName(); - - // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later. - private static Class<?> getCursorAnchorInfoRequestClass() { - try { - return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest"); - } catch (ClassNotFoundException e) { - return null; - } - } - - private static final Class<?> TYPE_CursorAnchorInfoRequest; - private static final Constructor<?> CONSTRUCTOR_CursorAnchorInfoRequest; - private static final Method METHOD_requestCursorAnchorInfo; + private static final CompatUtils.ClassWrapper sInputConnectionType; + private static final CompatUtils.ToBooleanMethodWrapper sRequestCursorUpdatesMethod; static { - TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass(); - CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor( - TYPE_CursorAnchorInfoRequest, int.class, int.class); - METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class, - "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest); + sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class); + sRequestCursorUpdatesMethod = sInputConnectionType.getPrimitiveMethod( + "requestCursorUpdates", false, int.class); } - public static boolean isRequestCursorAnchorInfoAvailable() { - return METHOD_requestCursorAnchorInfo != null && - CONSTRUCTOR_CursorAnchorInfoRequest != null; + public static boolean isRequestCursorUpdatesAvailable() { + return sRequestCursorUpdatesMethod != null; } /** - * Local copies of some constants in CursorAnchorInfoRequest until the SDK becomes publicly - * available. + * Local copies of some constants in InputConnection until the SDK becomes publicly available. */ - private final static int RESULT_NOT_HANDLED = 0; - private final static int RESULT_SCHEDULED = 1; - private final static int TYPE_CURSOR_ANCHOR_INFO = 1; - private final static int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 1; - private final static int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 2; - private final static int TYPE_CURSOR_RECT = 2; - private final static int FLAG_CURSOR_RECT_MONITOR = 1; - private final static int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 2; - private final static int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 4; + private static int CURSOR_UPDATE_IMMEDIATE = 1 << 0; + private static int CURSOR_UPDATE_MONITOR = 1 << 1; - private static int requestCursorAnchorInfoImpl(final InputConnection inputConnection, - final int type, final int flags) { - if (!isRequestCursorAnchorInfoAvailable()) { - return RESULT_NOT_HANDLED; - } - final Object requestObject = CompatUtils.newInstance( - CONSTRUCTOR_CursorAnchorInfoRequest, type, flags); - if (requestObject == null) { - return RESULT_NOT_HANDLED; + private static boolean requestCursorUpdatesImpl(final InputConnection inputConnection, + final int cursorUpdateMode) { + if (!isRequestCursorUpdatesAvailable()) { + return false; } - return (Integer) CompatUtils.invoke(inputConnection, - RESULT_NOT_HANDLED /* defaultValue */, - METHOD_requestCursorAnchorInfo, requestObject); + return sRequestCursorUpdatesMethod.invoke(inputConnection, cursorUpdateMode); } /** @@ -88,47 +55,10 @@ public final class InputConnectionCompatUtils { * as soon as possible to notify the current cursor/anchor position to the input method. * @return {@code false} if the request is not handled. Otherwise returns {@code true}. */ - public static boolean requestCursorAnchorInfo(final InputConnection inputConnection, + public static boolean requestCursorUpdates(final InputConnection inputConnection, final boolean enableMonitor, final boolean requestImmediateCallback) { - final int requestFlags = (enableMonitor ? FLAG_CURSOR_ANCHOR_INFO_MONITOR : 0) - | (requestImmediateCallback ? FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE : 0); - final int requestResult = requestCursorAnchorInfoImpl(inputConnection, - TYPE_CURSOR_ANCHOR_INFO, requestFlags); - switch (requestResult) { - case RESULT_NOT_HANDLED: - return false; - case RESULT_SCHEDULED: - return true; - default: - Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult - + " for type=TYPE_CURSOR_ANCHOR_INFO flags=" + requestFlags); - return true; - } - } - - /** - * Requests the editor to call back {@link InputMethodManager#updateCursor}. - * @param inputConnection the input connection to which the request is to be sent. - * @param enableMonitor {@code true} to request the editor to call back the method whenever the - * cursor position is changed. - * @return {@code false} if the request is not handled. Otherwise returns {@code true}. - */ - public static boolean requestCursorRect(final InputConnection inputConnection, - final boolean enableMonitor) { - final int requestFlags = enableMonitor ? - FLAG_CURSOR_RECT_MONITOR | FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES | - FLAG_CURSOR_RECT_WITH_VIEW_MATRIX : 0; - final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_RECT, - requestFlags); - switch (requestResult) { - case RESULT_NOT_HANDLED: - return false; - case RESULT_SCHEDULED: - return true; - default: - Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult - + " for type=TYPE_CURSOR_RECT flags=" + requestFlags); - return true; - } + final int cursorUpdateMode = (enableMonitor ? CURSOR_UPDATE_MONITOR : 0) + | (requestImmediateCallback ? CURSOR_UPDATE_IMMEDIATE : 0); + return requestCursorUpdatesImpl(inputConnection, cursorUpdateMode); } } diff --git a/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java new file mode 100644 index 000000000..eb180071e --- /dev/null +++ b/java/src/com/android/inputmethod/compat/NotificationCompatUtils.java @@ -0,0 +1,83 @@ +/* + * 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.app.Notification; +import android.os.Build; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class NotificationCompatUtils { + // Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later. + private static final Method METHOD_setColor = + CompatUtils.getMethod(Notification.Builder.class, "setColor", int.class); + private static final Method METHOD_setVisibility = + CompatUtils.getMethod(Notification.Builder.class, "setVisibility", int.class); + private static final Method METHOD_setCategory = + CompatUtils.getMethod(Notification.Builder.class, "setCategory", String.class); + private static final Method METHOD_setPriority = + CompatUtils.getMethod(Notification.Builder.class, "setPriority", int.class); + private static final Method METHOD_build = + CompatUtils.getMethod(Notification.Builder.class, "build"); + private static final Field FIELD_VISIBILITY_SECRET = + CompatUtils.getField(Notification.class, "VISIBILITY_SECRET"); + private static final int VISIBILITY_SECRET = null == FIELD_VISIBILITY_SECRET ? 0 + : (Integer) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */, + FIELD_VISIBILITY_SECRET); + private static final Field FIELD_CATEGORY_RECOMMENDATION = + CompatUtils.getField(Notification.class, "CATEGORY_RECOMMENDATION"); + private static final String CATEGORY_RECOMMENDATION = null == FIELD_CATEGORY_RECOMMENDATION ? "" + : (String) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */, + FIELD_CATEGORY_RECOMMENDATION); + private static final Field FIELD_PRIORITY_LOW = + CompatUtils.getField(Notification.class, "PRIORITY_LOW"); + private static final int PRIORITY_LOW = null == FIELD_PRIORITY_LOW ? 0 + : (Integer) CompatUtils.getFieldValue(null /* receiver */, null /* defaultValue */, + FIELD_PRIORITY_LOW); + + private NotificationCompatUtils() { + // This class is non-instantiable. + } + + // Sets the accent color + public static void setColor(final Notification.Builder builder, final int color) { + CompatUtils.invoke(builder, null, METHOD_setColor, color); + } + + public static void setVisibilityToSecret(final Notification.Builder builder) { + CompatUtils.invoke(builder, null, METHOD_setVisibility, VISIBILITY_SECRET); + } + + public static void setCategoryToRecommendation(final Notification.Builder builder) { + CompatUtils.invoke(builder, null, METHOD_setCategory, CATEGORY_RECOMMENDATION); + } + + public static void setPriorityToLow(final Notification.Builder builder) { + CompatUtils.invoke(builder, null, METHOD_setPriority, PRIORITY_LOW); + } + + 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(); + } + } +} diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index c07997bc9..c33c01552 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -68,7 +68,7 @@ public final class SuggestionSpanUtils { public static CharSequence getTextWithSuggestionSpan(final Context context, final String pickedWord, final SuggestedWords suggestedWords) { if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty() - || suggestedWords.mIsPrediction || suggestedWords.isPunctuationSuggestions()) { + || suggestedWords.isPrediction() || suggestedWords.isPunctuationSuggestions()) { return pickedWord; } diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java index afbe8c890..0f00be133 100644 --- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java @@ -34,6 +34,9 @@ public final class ViewCompatUtils { // 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); private ViewCompatUtils() { // This utility class is not publicly instantiable. @@ -56,9 +59,19 @@ public final class ViewCompatUtils { } public static void setElevation(final View view, final float elevation) { - if (METHOD_setElevation == null) { - return; - } 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; + public static final int TEXT_ALIGNMENT_TEXT_START = 2; + public static final int TEXT_ALIGNMENT_TEXT_END = 3; + public static final int TEXT_ALIGNMENT_CENTER = 4; + public static final int TEXT_ALIGNMENT_VIEW_START = 5; + public static final int TEXT_ALIGNMENT_VIEW_END = 6; + + public static void setTextAlignment(final View view, final int textAlignment) { + CompatUtils.invoke(view, null, METHOD_setTextAlignment, textAlignment); + } } |