diff options
Diffstat (limited to 'java/src/com/android/inputmethod/compat')
4 files changed, 154 insertions, 59 deletions
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java index 24eaec85c..5af31795c 100644 --- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java @@ -23,39 +23,28 @@ import com.android.inputmethod.annotations.UsedForTesting; @UsedForTesting public final class CursorAnchorInfoCompatWrapper { - 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; - - /** - * Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible. - */ - public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; - - /** - * 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; + 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.ToObjectMethodWrapper<RectF> sGetCharacterRectMethod; - private static final CompatUtils.ToIntMethodWrapper sGetCharacterRectFlagsMethod; + 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; @@ -63,20 +52,24 @@ public final class CursorAnchorInfoCompatWrapper { private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod; private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod; private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod; - private static final CompatUtils.ToBooleanMethodWrapper sIsInsertionMarkerClippedMethod; + private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod; - private static int COMPOSING_TEXT_START_DEFAULT = -1; + private static int INVALID_TEXT_INDEX = -1; static { sCursorAnchorInfoClass = CompatUtils.getClassWrapper( "android.view.inputmethod.CursorAnchorInfo"); - sGetCharacterRectMethod = sCursorAnchorInfoClass.getMethod( - "getCharacterRect", (RectF)null, int.class); - sGetCharacterRectFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod( - "getCharacterRectFlags", CHARACTER_RECT_TYPE_UNSPECIFIED, int.class); + 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", COMPOSING_TEXT_START_DEFAULT); + "getComposingTextStart", INVALID_TEXT_INDEX); sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod( "getInsertionMarkerBaseline", 0.0f); sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod( @@ -86,13 +79,13 @@ public final class CursorAnchorInfoCompatWrapper { sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod( "getInsertionMarkerTop", 0.0f); sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null); - sIsInsertionMarkerClippedMethod = sCursorAnchorInfoClass.getPrimitiveMethod( - "isInsertionMarkerClipped", false); + sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod( + "getInsertionMarkerFlags", 0); } @UsedForTesting - public static boolean isAvailable() { - return sCursorAnchorInfoClass.exists(); + public boolean isAvailable() { + return sCursorAnchorInfoClass.exists() && mInstance != null; } private Object mInstance; @@ -103,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); @@ -118,6 +111,14 @@ 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 sGetComposingTextMethod.invoke(mInstance); } @@ -130,12 +131,12 @@ public final class CursorAnchorInfoCompatWrapper { return sGetMatrixMethod.invoke(mInstance); } - public RectF getCharacterRect(final int index) { - return sGetCharacterRectMethod.invoke(mInstance, index); + public RectF getCharacterBounds(final int index) { + return sGetCharacterBoundsMethod.invoke(mInstance, index); } - public int getCharacterRectFlags(final int index) { - return sGetCharacterRectFlagsMethod.invoke(mInstance, index); + public int getCharacterBoundsFlags(final int index) { + return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index); } public float getInsertionMarkerBaseline() { @@ -154,7 +155,7 @@ public final class CursorAnchorInfoCompatWrapper { return sGetInsertionMarkerTopMethod.invoke(mInstance); } - public boolean isInsertionMarkerClipped() { - return sIsInsertionMarkerClippedMethod.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 862ec8a58..a5c71b22f 100644 --- a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java @@ -21,30 +21,29 @@ import android.view.inputmethod.InputMethodManager; public final class InputConnectionCompatUtils { private static final CompatUtils.ClassWrapper sInputConnectionType; - private static final CompatUtils.ToBooleanMethodWrapper sRequestUpdateCursorAnchorInfoMethod; + private static final CompatUtils.ToBooleanMethodWrapper sRequestCursorUpdatesMethod; static { sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class); - sRequestUpdateCursorAnchorInfoMethod = sInputConnectionType.getPrimitiveMethod( - "requestUpdateCursorAnchorInfo", false, int.class); + sRequestCursorUpdatesMethod = sInputConnectionType.getPrimitiveMethod( + "requestCursorUpdates", false, int.class); } - public static boolean isRequestUpdateCursorAnchorInfoAvailable() { - return sRequestUpdateCursorAnchorInfoMethod != 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 static int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0; - private static int REQUEST_UPDATE_CURSOR_UPDATE_MONITOR = 1 << 1; + private static int CURSOR_UPDATE_IMMEDIATE = 1 << 0; + private static int CURSOR_UPDATE_MONITOR = 1 << 1; - private static boolean requestUpdateCursorAnchorInfoImpl(final InputConnection inputConnection, + private static boolean requestCursorUpdatesImpl(final InputConnection inputConnection, final int cursorUpdateMode) { - if (!isRequestUpdateCursorAnchorInfoAvailable()) { + if (!isRequestCursorUpdatesAvailable()) { return false; } - return sRequestUpdateCursorAnchorInfoMethod.invoke(inputConnection, cursorUpdateMode); + return sRequestCursorUpdatesMethod.invoke(inputConnection, cursorUpdateMode); } /** @@ -56,11 +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 requestUpdateCursorAnchorInfo(final InputConnection inputConnection, + public static boolean requestCursorUpdates(final InputConnection inputConnection, final boolean enableMonitor, final boolean requestImmediateCallback) { - final int cursorUpdateMode = (enableMonitor ? REQUEST_UPDATE_CURSOR_UPDATE_MONITOR : 0) - | (requestImmediateCallback ? REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE : 0); - return requestUpdateCursorAnchorInfoImpl(inputConnection, cursorUpdateMode); + 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/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); + } } |