Loading java/src/com/android/inputmethod/compat/TextInfoCompatUtils.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * 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.view.textservice.TextInfo; import com.android.inputmethod.annotations.UsedForTesting; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Locale; @UsedForTesting public final class TextInfoCompatUtils { // Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later. private static final Method TEXT_INFO_GET_CHAR_SEQUENCE = CompatUtils.getMethod(TextInfo.class, "getCharSequence"); private static final Constructor<?> TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE = CompatUtils.getConstructor(TextInfo.class, CharSequence.class, int.class, int.class, int.class, int.class); @UsedForTesting public static boolean isCharSequenceSupported() { return TEXT_INFO_GET_CHAR_SEQUENCE != null && TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null; } @UsedForTesting public static TextInfo newInstance(CharSequence charSequence, int start, int end, int cookie, int sequenceNumber) { if (TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null) { return (TextInfo) CompatUtils.newInstance(TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE, charSequence, start, end, cookie, sequenceNumber); } return new TextInfo(charSequence.subSequence(start, end).toString(), cookie, sequenceNumber); } @UsedForTesting public static CharSequence getCharSequence(final TextInfo textInfo, final CharSequence defaultValue) { return (CharSequence) CompatUtils.invoke(textInfo, defaultValue, TEXT_INFO_GET_CHAR_SEQUENCE); } } tests/src/com/android/inputmethod/compat/TextInfoCompatUtilsTests.java 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * 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.graphics.Typeface; import android.os.Parcel; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.text.style.StyleSpan; import android.text.style.URLSpan; import android.view.textservice.TextInfo; import java.util.Arrays; @SmallTest public class TextInfoCompatUtilsTests extends AndroidTestCase { final private static String TEST_TEXT = "0123456789"; final private static int TEST_COOKIE = 0x1234; final private static int TEST_SEQUENCE_NUMBER = 0x4321; final private static int TEST_CHAR_SEQUENCE_START = 1; final private static int TEST_CHAR_SEQUENCE_END = 6; final private static StyleSpan TEST_STYLE_SPAN = new StyleSpan(Typeface.BOLD); final private static int TEST_STYLE_SPAN_START = 4; final private static int TEST_STYLE_SPAN_END = 5; final private static int TEST_STYLE_SPAN_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE; final private static URLSpan TEST_URL_SPAN_URL = new URLSpan("http://example.com"); final private static int TEST_URL_SPAN_START = 3; final private static int TEST_URL_SPAN_END = 7; final private static int TEST_URL_SPAN_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; public void testGetCharSequence() { final SpannableString text = new SpannableString(TEST_TEXT); text.setSpan(TEST_STYLE_SPAN, TEST_STYLE_SPAN_START, TEST_STYLE_SPAN_END, TEST_STYLE_SPAN_FLAGS); text.setSpan(TEST_URL_SPAN_URL, TEST_URL_SPAN_START, TEST_URL_SPAN_END, TEST_URL_SPAN_FLAGS); final TextInfo textInfo = TextInfoCompatUtils.newInstance(text, TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END, TEST_COOKIE, TEST_SEQUENCE_NUMBER); final Spanned expectedSpanned = (Spanned) text.subSequence(TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END); final CharSequence actualCharSequence = TextInfoCompatUtils.getCharSequence(textInfo, null); // This should be valid even if TextInfo#getCharSequence is not supported. assertTrue(TextUtils.equals(expectedSpanned, actualCharSequence)); if (TextInfoCompatUtils.isCharSequenceSupported()) { // This is valid only if TextInfo#getCharSequence is supported. assertTrue("should be Spanned", actualCharSequence instanceof Spanned); assertTrue(Arrays.equals(marshall(expectedSpanned), marshall(actualCharSequence))); } } private static byte[] marshall(final CharSequence cahrSequence) { Parcel parcel = null; try { parcel = Parcel.obtain(); TextUtils.writeToParcel(cahrSequence, parcel, 0); return parcel.marshall(); } finally { if (parcel != null) { parcel.recycle(); parcel = null; } } } } Loading
java/src/com/android/inputmethod/compat/TextInfoCompatUtils.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * 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.view.textservice.TextInfo; import com.android.inputmethod.annotations.UsedForTesting; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Locale; @UsedForTesting public final class TextInfoCompatUtils { // Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later. private static final Method TEXT_INFO_GET_CHAR_SEQUENCE = CompatUtils.getMethod(TextInfo.class, "getCharSequence"); private static final Constructor<?> TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE = CompatUtils.getConstructor(TextInfo.class, CharSequence.class, int.class, int.class, int.class, int.class); @UsedForTesting public static boolean isCharSequenceSupported() { return TEXT_INFO_GET_CHAR_SEQUENCE != null && TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null; } @UsedForTesting public static TextInfo newInstance(CharSequence charSequence, int start, int end, int cookie, int sequenceNumber) { if (TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE != null) { return (TextInfo) CompatUtils.newInstance(TEXT_INFO_CONSTRUCTOR_FOR_CHAR_SEQUENCE, charSequence, start, end, cookie, sequenceNumber); } return new TextInfo(charSequence.subSequence(start, end).toString(), cookie, sequenceNumber); } @UsedForTesting public static CharSequence getCharSequence(final TextInfo textInfo, final CharSequence defaultValue) { return (CharSequence) CompatUtils.invoke(textInfo, defaultValue, TEXT_INFO_GET_CHAR_SEQUENCE); } }
tests/src/com/android/inputmethod/compat/TextInfoCompatUtilsTests.java 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * 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.graphics.Typeface; import android.os.Parcel; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.text.style.StyleSpan; import android.text.style.URLSpan; import android.view.textservice.TextInfo; import java.util.Arrays; @SmallTest public class TextInfoCompatUtilsTests extends AndroidTestCase { final private static String TEST_TEXT = "0123456789"; final private static int TEST_COOKIE = 0x1234; final private static int TEST_SEQUENCE_NUMBER = 0x4321; final private static int TEST_CHAR_SEQUENCE_START = 1; final private static int TEST_CHAR_SEQUENCE_END = 6; final private static StyleSpan TEST_STYLE_SPAN = new StyleSpan(Typeface.BOLD); final private static int TEST_STYLE_SPAN_START = 4; final private static int TEST_STYLE_SPAN_END = 5; final private static int TEST_STYLE_SPAN_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE; final private static URLSpan TEST_URL_SPAN_URL = new URLSpan("http://example.com"); final private static int TEST_URL_SPAN_START = 3; final private static int TEST_URL_SPAN_END = 7; final private static int TEST_URL_SPAN_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; public void testGetCharSequence() { final SpannableString text = new SpannableString(TEST_TEXT); text.setSpan(TEST_STYLE_SPAN, TEST_STYLE_SPAN_START, TEST_STYLE_SPAN_END, TEST_STYLE_SPAN_FLAGS); text.setSpan(TEST_URL_SPAN_URL, TEST_URL_SPAN_START, TEST_URL_SPAN_END, TEST_URL_SPAN_FLAGS); final TextInfo textInfo = TextInfoCompatUtils.newInstance(text, TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END, TEST_COOKIE, TEST_SEQUENCE_NUMBER); final Spanned expectedSpanned = (Spanned) text.subSequence(TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END); final CharSequence actualCharSequence = TextInfoCompatUtils.getCharSequence(textInfo, null); // This should be valid even if TextInfo#getCharSequence is not supported. assertTrue(TextUtils.equals(expectedSpanned, actualCharSequence)); if (TextInfoCompatUtils.isCharSequenceSupported()) { // This is valid only if TextInfo#getCharSequence is supported. assertTrue("should be Spanned", actualCharSequence instanceof Spanned); assertTrue(Arrays.equals(marshall(expectedSpanned), marshall(actualCharSequence))); } } private static byte[] marshall(final CharSequence cahrSequence) { Parcel parcel = null; try { parcel = Parcel.obtain(); TextUtils.writeToParcel(cahrSequence, parcel, 0); return parcel.marshall(); } finally { if (parcel != null) { parcel.recycle(); parcel = null; } } } }