upload android base code part8
16
android/packages/inputmethods/LatinIME/Android.mk
Normal file
|
@ -0,0 +1,16 @@
|
|||
# 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.
|
||||
|
||||
subdirs := common native java tests tools
|
||||
include $(call all-named-subdir-makefiles, $(subdirs))
|
57
android/packages/inputmethods/LatinIME/CleanSpec.mk
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Copyright (C) 2007 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.
|
||||
#
|
||||
|
||||
# If you don't need to do a full clean build but would like to touch
|
||||
# a file or delete some intermediate files, add a clean step to the end
|
||||
# of the list. These steps will only be run once, if they haven't been
|
||||
# run before.
|
||||
#
|
||||
# E.g.:
|
||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||
#
|
||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||
# files that are missing or have been moved.
|
||||
#
|
||||
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||
#
|
||||
# If you need to re-do something that's already mentioned, just copy
|
||||
# the command and add it to the bottom of the list. E.g., if a change
|
||||
# that you made last week required touching a file and a change you
|
||||
# made today requires touching the same file, just copy the old
|
||||
# touch step and add it to the end of the list.
|
||||
#
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
|
||||
# For example:
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||
|
||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/LatinIME*)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/LatinIME.apk)
|
||||
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libjni_latinime_intermediates)
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
28
android/packages/inputmethods/LatinIME/common/Android.mk
Normal file
|
@ -0,0 +1,28 @@
|
|||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := latinime-common
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := jsr305
|
||||
LOCAL_SDK_VERSION := 21
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
|
||||
# Also build a host side library
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := latinime-common-host
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := jsr305lib
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.annotations;
|
||||
|
||||
/**
|
||||
* Denotes that the class, method or field should not be eliminated by ProGuard,
|
||||
* because it is externally referenced. (See proguard.flags)
|
||||
*/
|
||||
public @interface ExternallyReferenced {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.annotations;
|
||||
|
||||
/**
|
||||
* Denotes that the class, method or field should not be eliminated by ProGuard,
|
||||
* so that unit tests can access it. (See proguard.flags)
|
||||
*/
|
||||
public @interface UsedForTesting {
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
// Utility methods related with code points used for tests.
|
||||
// TODO: Figure out where this class should be.
|
||||
@UsedForTesting
|
||||
public class CodePointUtils {
|
||||
private CodePointUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static final int[] LATIN_ALPHABETS_LOWER = {
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */,
|
||||
0x00E1 /* LATIN SMALL LETTER A WITH ACUTE */,
|
||||
0x00E2 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */,
|
||||
0x00E3 /* LATIN SMALL LETTER A WITH TILDE */,
|
||||
0x00E4 /* LATIN SMALL LETTER A WITH DIAERESIS */,
|
||||
0x00E5 /* LATIN SMALL LETTER A WITH RING ABOVE */,
|
||||
0x00E6 /* LATIN SMALL LETTER AE */,
|
||||
0x00E7 /* LATIN SMALL LETTER C WITH CEDILLA */,
|
||||
0x00E8 /* LATIN SMALL LETTER E WITH GRAVE */,
|
||||
0x00E9 /* LATIN SMALL LETTER E WITH ACUTE */,
|
||||
0x00EA /* LATIN SMALL LETTER E WITH CIRCUMFLEX */,
|
||||
0x00EB /* LATIN SMALL LETTER E WITH DIAERESIS */,
|
||||
0x00EC /* LATIN SMALL LETTER I WITH GRAVE */,
|
||||
0x00ED /* LATIN SMALL LETTER I WITH ACUTE */,
|
||||
0x00EE /* LATIN SMALL LETTER I WITH CIRCUMFLEX */,
|
||||
0x00EF /* LATIN SMALL LETTER I WITH DIAERESIS */,
|
||||
0x00F0 /* LATIN SMALL LETTER ETH */,
|
||||
0x00F1 /* LATIN SMALL LETTER N WITH TILDE */,
|
||||
0x00F2 /* LATIN SMALL LETTER O WITH GRAVE */,
|
||||
0x00F3 /* LATIN SMALL LETTER O WITH ACUTE */,
|
||||
0x00F4 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */,
|
||||
0x00F5 /* LATIN SMALL LETTER O WITH TILDE */,
|
||||
0x00F6 /* LATIN SMALL LETTER O WITH DIAERESIS */,
|
||||
0x00F7 /* LATIN SMALL LETTER O WITH STROKE */,
|
||||
0x00F9 /* LATIN SMALL LETTER U WITH GRAVE */,
|
||||
0x00FA /* LATIN SMALL LETTER U WITH ACUTE */,
|
||||
0x00FB /* LATIN SMALL LETTER U WITH CIRCUMFLEX */,
|
||||
0x00FC /* LATIN SMALL LETTER U WITH DIAERESIS */,
|
||||
0x00FD /* LATIN SMALL LETTER Y WITH ACUTE */,
|
||||
0x00FE /* LATIN SMALL LETTER THORN */,
|
||||
0x00FF /* LATIN SMALL LETTER Y WITH DIAERESIS */
|
||||
};
|
||||
|
||||
@UsedForTesting
|
||||
@Nonnull
|
||||
public static int[] generateCodePointSet(final int codePointSetSize,
|
||||
@Nonnull final Random random) {
|
||||
final int[] codePointSet = new int[codePointSetSize];
|
||||
for (int i = codePointSet.length - 1; i >= 0; ) {
|
||||
final int r = Math.abs(random.nextInt());
|
||||
if (r < 0) {
|
||||
continue;
|
||||
}
|
||||
// Don't insert 0~0x20, but insert any other code point.
|
||||
// Code points are in the range 0~0x10FFFF.
|
||||
final int candidateCodePoint = 0x20 + r % (Character.MAX_CODE_POINT - 0x20);
|
||||
// Code points between MIN_ and MAX_SURROGATE are not valid on their own.
|
||||
if (candidateCodePoint >= Character.MIN_SURROGATE
|
||||
&& candidateCodePoint <= Character.MAX_SURROGATE) {
|
||||
continue;
|
||||
}
|
||||
codePointSet[i] = candidateCodePoint;
|
||||
--i;
|
||||
}
|
||||
return codePointSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random word.
|
||||
*/
|
||||
@UsedForTesting
|
||||
@Nonnull
|
||||
public static String generateWord(@Nonnull final Random random,
|
||||
@Nonnull final int[] codePointSet) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
// 8 * 4 = 32 chars max, but we do it the following way so as to bias the random toward
|
||||
// longer words. This should be closer to natural language, and more importantly, it will
|
||||
// exercise the algorithms in dicttool much more.
|
||||
final int count = 1 + (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5)
|
||||
+ (Math.abs(random.nextInt()) % 5);
|
||||
while (builder.length() < count) {
|
||||
builder.appendCodePoint(codePointSet[Math.abs(random.nextInt()) % codePointSet.length]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Utility methods for working with collections.
|
||||
*/
|
||||
public final class CollectionUtils {
|
||||
private CollectionUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a sub-range of the given array to an ArrayList of the appropriate type.
|
||||
* @param array Array to be converted.
|
||||
* @param start First index inclusive to be converted.
|
||||
* @param end Last index exclusive to be converted.
|
||||
* @throws IllegalArgumentException if start or end are out of range or start > end.
|
||||
*/
|
||||
@Nonnull
|
||||
public static <E> ArrayList<E> arrayAsList(@Nonnull final E[] array, final int start,
|
||||
final int end) {
|
||||
if (start < 0 || start > end || end > array.length) {
|
||||
throw new IllegalArgumentException("Invalid start: " + start + " end: " + end
|
||||
+ " with array.length: " + array.length);
|
||||
}
|
||||
|
||||
final ArrayList<E> list = new ArrayList<>(end - start);
|
||||
for (int i = start; i < end; i++) {
|
||||
list.add(array[i]);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether c contains no elements, true if c is null or c is empty.
|
||||
* @param c Collection to test.
|
||||
* @return Whether c contains no elements.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public static boolean isNullOrEmpty(@Nullable final Collection c) {
|
||||
return c == null || c.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether map contains no elements, true if map is null or map is empty.
|
||||
* @param map Map to test.
|
||||
* @return Whether map contains no elements.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public static boolean isNullOrEmpty(@Nullable final Map map) {
|
||||
return map == null || map.isEmpty();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.latin.common;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An immutable class that encapsulates a snapshot of word composition data.
|
||||
*/
|
||||
public class ComposedData {
|
||||
@Nonnull
|
||||
public final InputPointers mInputPointers;
|
||||
public final boolean mIsBatchMode;
|
||||
@Nonnull
|
||||
public final String mTypedWord;
|
||||
|
||||
public ComposedData(@Nonnull final InputPointers inputPointers, final boolean isBatchMode,
|
||||
@Nonnull final String typedWord) {
|
||||
mInputPointers = inputPointers;
|
||||
mIsBatchMode = isBatchMode;
|
||||
mTypedWord = typedWord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the code points in the typed word to a destination array of ints.
|
||||
*
|
||||
* If the array is too small to hold the code points in the typed word, nothing is copied and
|
||||
* -1 is returned.
|
||||
*
|
||||
* @param destination the array of ints.
|
||||
* @return the number of copied code points.
|
||||
*/
|
||||
public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
|
||||
@Nonnull final int[] destination) {
|
||||
// lastIndex is exclusive
|
||||
final int lastIndex = mTypedWord.length()
|
||||
- StringUtils.getTrailingSingleQuotesCount(mTypedWord);
|
||||
if (lastIndex <= 0) {
|
||||
// The string is empty or contains only single quotes.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The following function counts the number of code points in the text range which begins
|
||||
// at index 0 and extends to the character at lastIndex.
|
||||
final int codePointSize = Character.codePointCount(mTypedWord, 0, lastIndex);
|
||||
if (codePointSize > destination.length) {
|
||||
return -1;
|
||||
}
|
||||
return StringUtils.copyCodePointsAndReturnCodePointCount(destination, mTypedWord, 0,
|
||||
lastIndex, true /* downCase */);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class Constants {
|
||||
|
||||
public static final class Color {
|
||||
/**
|
||||
* The alpha value for fully opaque.
|
||||
*/
|
||||
public final static int ALPHA_OPAQUE = 255;
|
||||
}
|
||||
|
||||
public static final class ImeOption {
|
||||
/**
|
||||
* The private IME option used to indicate that no microphone should be shown for a given
|
||||
* text field. For instance, this is specified by the search dialog when the dialog is
|
||||
* already showing a voice search button.
|
||||
*
|
||||
* @deprecated Use {@link ImeOption#NO_MICROPHONE} with package name prefixed.
|
||||
*/
|
||||
@SuppressWarnings("dep-ann")
|
||||
public static final String NO_MICROPHONE_COMPAT = "nm";
|
||||
|
||||
/**
|
||||
* The private IME option used to indicate that no microphone should be shown for a given
|
||||
* text field. For instance, this is specified by the search dialog when the dialog is
|
||||
* already showing a voice search button.
|
||||
*/
|
||||
public static final String NO_MICROPHONE = "noMicrophoneKey";
|
||||
|
||||
/**
|
||||
* The private IME option used to indicate that no settings key should be shown for a given
|
||||
* text field.
|
||||
*/
|
||||
public static final String NO_SETTINGS_KEY = "noSettingsKey";
|
||||
|
||||
/**
|
||||
* The private IME option used to indicate that the given text field needs ASCII code points
|
||||
* input.
|
||||
*
|
||||
* @deprecated Use EditorInfo#IME_FLAG_FORCE_ASCII.
|
||||
*/
|
||||
@SuppressWarnings("dep-ann")
|
||||
public static final String FORCE_ASCII = "forceAscii";
|
||||
|
||||
/**
|
||||
* The private IME option used to suppress the floating gesture preview for a given text
|
||||
* field. This overrides the corresponding keyboard settings preference.
|
||||
* {@link com.android.inputmethod.latin.settings.SettingsValues#mGestureFloatingPreviewTextEnabled}
|
||||
*/
|
||||
public static final String NO_FLOATING_GESTURE_PREVIEW = "noGestureFloatingPreview";
|
||||
|
||||
private ImeOption() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Subtype {
|
||||
/**
|
||||
* The subtype mode used to indicate that the subtype is a keyboard.
|
||||
*/
|
||||
public static final String KEYBOARD_MODE = "keyboard";
|
||||
|
||||
public static final class ExtraValue {
|
||||
/**
|
||||
* The subtype extra value used to indicate that this subtype is capable of
|
||||
* entering ASCII characters.
|
||||
*/
|
||||
public static final String ASCII_CAPABLE = "AsciiCapable";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate that this subtype is enabled
|
||||
* when the default subtype is not marked as ascii capable.
|
||||
*/
|
||||
public static final String ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
|
||||
"EnabledWhenDefaultIsNotAsciiCapable";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate that this subtype is capable of
|
||||
* entering emoji characters.
|
||||
*/
|
||||
public static final String EMOJI_CAPABLE = "EmojiCapable";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate that this subtype requires a network
|
||||
* connection to work.
|
||||
*/
|
||||
public static final String REQ_NETWORK_CONNECTIVITY = "requireNetworkConnectivity";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate that the display name of this subtype
|
||||
* contains a "%s" for printf-like replacement and it should be replaced by
|
||||
* this extra value.
|
||||
* This extra value is supported on JellyBean and later.
|
||||
*/
|
||||
public static final String UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME =
|
||||
"UntranslatableReplacementStringInSubtypeName";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate this subtype keyboard layout set name.
|
||||
* This extra value is private to LatinIME.
|
||||
*/
|
||||
public static final String KEYBOARD_LAYOUT_SET = "KeyboardLayoutSet";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to indicate that this subtype is an additional subtype
|
||||
* that the user defined. This extra value is private to LatinIME.
|
||||
*/
|
||||
public static final String IS_ADDITIONAL_SUBTYPE = "isAdditionalSubtype";
|
||||
|
||||
/**
|
||||
* The subtype extra value used to specify the combining rules.
|
||||
*/
|
||||
public static final String COMBINING_RULES = "CombiningRules";
|
||||
|
||||
private ExtraValue() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
}
|
||||
|
||||
private Subtype() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
}
|
||||
|
||||
public static final class TextUtils {
|
||||
/**
|
||||
* Capitalization mode for {@link android.text.TextUtils#getCapsMode}: don't capitalize
|
||||
* characters. This value may be used with
|
||||
* {@link android.text.TextUtils#CAP_MODE_CHARACTERS},
|
||||
* {@link android.text.TextUtils#CAP_MODE_WORDS}, and
|
||||
* {@link android.text.TextUtils#CAP_MODE_SENTENCES}.
|
||||
*/
|
||||
// TODO: Straighten this out. It's bizarre to have to use android.text.TextUtils.CAP_MODE_*
|
||||
// except for OFF that is in Constants.TextUtils.
|
||||
public static final int CAP_MODE_OFF = 0;
|
||||
|
||||
private TextUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
}
|
||||
|
||||
public static final int NOT_A_CODE = -1;
|
||||
public static final int NOT_A_CURSOR_POSITION = -1;
|
||||
// TODO: replace the following constants with state in InputTransaction?
|
||||
public static final int NOT_A_COORDINATE = -1;
|
||||
public static final int SUGGESTION_STRIP_COORDINATE = -2;
|
||||
public static final int EXTERNAL_KEYBOARD_COORDINATE = -4;
|
||||
|
||||
// A hint on how many characters to cache from the TextView. A good value of this is given by
|
||||
// how many characters we need to be able to almost always find the caps mode.
|
||||
public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024;
|
||||
// How many characters we accept for the recapitalization functionality. This needs to be
|
||||
// large enough for all reasonable purposes, but avoid purposeful attacks. 100k sounds about
|
||||
// right for this.
|
||||
public static final int MAX_CHARACTERS_FOR_RECAPITALIZATION = 1024 * 100;
|
||||
|
||||
// Key events coming any faster than this are long-presses.
|
||||
public static final int LONG_PRESS_MILLISECONDS = 200;
|
||||
// TODO: Set this value appropriately.
|
||||
public static final int GET_SUGGESTED_WORDS_TIMEOUT = 200;
|
||||
// How many continuous deletes at which to start deleting at a higher speed.
|
||||
public static final int DELETE_ACCELERATE_AT = 20;
|
||||
|
||||
public static final String WORD_SEPARATOR = " ";
|
||||
|
||||
public static boolean isValidCoordinate(final int coordinate) {
|
||||
// Detect {@link NOT_A_COORDINATE}, {@link SUGGESTION_STRIP_COORDINATE},
|
||||
// and {@link SPELL_CHECKER_COORDINATE}.
|
||||
return coordinate >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom request code used in
|
||||
* {@link com.android.inputmethod.keyboard.KeyboardActionListener#onCustomRequest(int)}.
|
||||
*/
|
||||
// The code to show input method picker.
|
||||
public static final int CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER = 1;
|
||||
|
||||
/**
|
||||
* Some common keys code. Must be positive.
|
||||
*/
|
||||
public static final int CODE_ENTER = '\n';
|
||||
public static final int CODE_TAB = '\t';
|
||||
public static final int CODE_SPACE = ' ';
|
||||
public static final int CODE_PERIOD = '.';
|
||||
public static final int CODE_COMMA = ',';
|
||||
public static final int CODE_DASH = '-';
|
||||
public static final int CODE_SINGLE_QUOTE = '\'';
|
||||
public static final int CODE_DOUBLE_QUOTE = '"';
|
||||
public static final int CODE_SLASH = '/';
|
||||
public static final int CODE_BACKSLASH = '\\';
|
||||
public static final int CODE_VERTICAL_BAR = '|';
|
||||
public static final int CODE_COMMERCIAL_AT = '@';
|
||||
public static final int CODE_PLUS = '+';
|
||||
public static final int CODE_PERCENT = '%';
|
||||
public static final int CODE_CLOSING_PARENTHESIS = ')';
|
||||
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
|
||||
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
|
||||
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
|
||||
public static final int CODE_INVERTED_QUESTION_MARK = 0xBF; // ¿
|
||||
public static final int CODE_INVERTED_EXCLAMATION_MARK = 0xA1; // ¡
|
||||
public static final int CODE_GRAVE_ACCENT = '`';
|
||||
public static final int CODE_CIRCUMFLEX_ACCENT = '^';
|
||||
public static final int CODE_TILDE = '~';
|
||||
|
||||
public static final String REGEXP_PERIOD = "\\.";
|
||||
public static final String STRING_SPACE = " ";
|
||||
|
||||
/**
|
||||
* Special keys code. Must be negative.
|
||||
* These should be aligned with constants in
|
||||
* {@link com.android.inputmethod.keyboard.internal.KeyboardCodesSet}.
|
||||
*/
|
||||
public static final int CODE_SHIFT = -1;
|
||||
public static final int CODE_CAPSLOCK = -2;
|
||||
public static final int CODE_SWITCH_ALPHA_SYMBOL = -3;
|
||||
public static final int CODE_OUTPUT_TEXT = -4;
|
||||
public static final int CODE_DELETE = -5;
|
||||
public static final int CODE_SETTINGS = -6;
|
||||
public static final int CODE_SHORTCUT = -7;
|
||||
public static final int CODE_ACTION_NEXT = -8;
|
||||
public static final int CODE_ACTION_PREVIOUS = -9;
|
||||
public static final int CODE_LANGUAGE_SWITCH = -10;
|
||||
public static final int CODE_EMOJI = -11;
|
||||
public static final int CODE_SHIFT_ENTER = -12;
|
||||
public static final int CODE_SYMBOL_SHIFT = -13;
|
||||
public static final int CODE_ALPHA_FROM_EMOJI = -14;
|
||||
// Code value representing the code is not specified.
|
||||
public static final int CODE_UNSPECIFIED = -15;
|
||||
|
||||
public static boolean isLetterCode(final int code) {
|
||||
return code >= CODE_SPACE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String printableCode(final int code) {
|
||||
switch (code) {
|
||||
case CODE_SHIFT: return "shift";
|
||||
case CODE_CAPSLOCK: return "capslock";
|
||||
case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
|
||||
case CODE_OUTPUT_TEXT: return "text";
|
||||
case CODE_DELETE: return "delete";
|
||||
case CODE_SETTINGS: return "settings";
|
||||
case CODE_SHORTCUT: return "shortcut";
|
||||
case CODE_ACTION_NEXT: return "actionNext";
|
||||
case CODE_ACTION_PREVIOUS: return "actionPrevious";
|
||||
case CODE_LANGUAGE_SWITCH: return "languageSwitch";
|
||||
case CODE_EMOJI: return "emoji";
|
||||
case CODE_SHIFT_ENTER: return "shiftEnter";
|
||||
case CODE_ALPHA_FROM_EMOJI: return "alpha";
|
||||
case CODE_UNSPECIFIED: return "unspec";
|
||||
case CODE_TAB: return "tab";
|
||||
case CODE_ENTER: return "enter";
|
||||
case CODE_SPACE: return "space";
|
||||
default:
|
||||
if (code < CODE_SPACE) return String.format("\\u%02X", code);
|
||||
if (code < 0x100) return String.format("%c", code);
|
||||
if (code < 0x10000) return String.format("\\u%04X", code);
|
||||
return String.format("\\U%05X", code);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String printableCodes(@Nonnull final int[] codes) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean addDelimiter = false;
|
||||
for (final int code : codes) {
|
||||
if (code == NOT_A_CODE) break;
|
||||
if (addDelimiter) sb.append(", ");
|
||||
sb.append(printableCode(code));
|
||||
addDelimiter = true;
|
||||
}
|
||||
return "[" + sb + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Screen metrics (a.k.a. Device form factor) constants of
|
||||
* {@link com.android.inputmethod.latin.R.integer#config_screen_metrics}.
|
||||
*/
|
||||
public static final int SCREEN_METRICS_SMALL_PHONE = 0;
|
||||
public static final int SCREEN_METRICS_LARGE_PHONE = 1;
|
||||
public static final int SCREEN_METRICS_LARGE_TABLET = 2;
|
||||
public static final int SCREEN_METRICS_SMALL_TABLET = 3;
|
||||
|
||||
@UsedForTesting
|
||||
public static boolean isPhone(final int screenMetrics) {
|
||||
return screenMetrics == SCREEN_METRICS_SMALL_PHONE
|
||||
|| screenMetrics == SCREEN_METRICS_LARGE_PHONE;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public static boolean isTablet(final int screenMetrics) {
|
||||
return screenMetrics == SCREEN_METRICS_SMALL_TABLET
|
||||
|| screenMetrics == SCREEN_METRICS_LARGE_TABLET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default capacity of gesture points container.
|
||||
* This constant is used by {@link com.android.inputmethod.keyboard.internal.BatchInputArbiter}
|
||||
* and etc. to preallocate regions that contain gesture event points.
|
||||
*/
|
||||
public static final int DEFAULT_GESTURE_POINTS_CAPACITY = 128;
|
||||
|
||||
public static final int MAX_IME_DECODER_RESULTS = 20;
|
||||
public static final int DECODER_SCORE_SCALAR = 1000000;
|
||||
public static final int DECODER_MAX_SCORE = 1000000000;
|
||||
|
||||
public static final int EVENT_BACKSPACE = 1;
|
||||
public static final int EVENT_REJECTION = 2;
|
||||
public static final int EVENT_REVERT = 3;
|
||||
|
||||
private Constants() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class CoordinateUtils {
|
||||
private static final int INDEX_X = 0;
|
||||
private static final int INDEX_Y = 1;
|
||||
private static final int ELEMENT_SIZE = INDEX_Y + 1;
|
||||
|
||||
private CoordinateUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] newInstance() {
|
||||
return new int[ELEMENT_SIZE];
|
||||
}
|
||||
|
||||
public static int x(@Nonnull final int[] coords) {
|
||||
return coords[INDEX_X];
|
||||
}
|
||||
|
||||
public static int y(@Nonnull final int[] coords) {
|
||||
return coords[INDEX_Y];
|
||||
}
|
||||
|
||||
public static void set(@Nonnull final int[] coords, final int x, final int y) {
|
||||
coords[INDEX_X] = x;
|
||||
coords[INDEX_Y] = y;
|
||||
}
|
||||
|
||||
public static void copy(@Nonnull final int[] destination, @Nonnull final int[] source) {
|
||||
destination[INDEX_X] = source[INDEX_X];
|
||||
destination[INDEX_Y] = source[INDEX_Y];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] newCoordinateArray(final int arraySize) {
|
||||
return new int[ELEMENT_SIZE * arraySize];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] newCoordinateArray(final int arraySize,
|
||||
final int defaultX, final int defaultY) {
|
||||
final int[] result = new int[ELEMENT_SIZE * arraySize];
|
||||
for (int i = 0; i < arraySize; ++i) {
|
||||
setXYInArray(result, i, defaultX, defaultY);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int xFromArray(@Nonnull final int[] coordsArray, final int index) {
|
||||
return coordsArray[ELEMENT_SIZE * index + INDEX_X];
|
||||
}
|
||||
|
||||
public static int yFromArray(@Nonnull final int[] coordsArray, final int index) {
|
||||
return coordsArray[ELEMENT_SIZE * index + INDEX_Y];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] coordinateFromArray(@Nonnull final int[] coordsArray, final int index) {
|
||||
final int[] coords = newInstance();
|
||||
set(coords, xFromArray(coordsArray, index), yFromArray(coordsArray, index));
|
||||
return coords;
|
||||
}
|
||||
|
||||
public static void setXYInArray(@Nonnull final int[] coordsArray, final int index,
|
||||
final int x, final int y) {
|
||||
final int baseIndex = ELEMENT_SIZE * index;
|
||||
coordsArray[baseIndex + INDEX_X] = x;
|
||||
coordsArray[baseIndex + INDEX_Y] = y;
|
||||
}
|
||||
|
||||
public static void setCoordinateInArray(@Nonnull final int[] coordsArray, final int index,
|
||||
@Nonnull final int[] coords) {
|
||||
setXYInArray(coordsArray, index, x(coords), y(coords));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.latin.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
/**
|
||||
* A simple class to help with removing directories recursively.
|
||||
*/
|
||||
public class FileUtils {
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
public static boolean deleteRecursively(final File path) {
|
||||
if (path.isDirectory()) {
|
||||
final File[] files = path.listFiles();
|
||||
if (files != null) {
|
||||
for (final File child : files) {
|
||||
deleteRecursively(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return path.delete();
|
||||
}
|
||||
|
||||
public static boolean deleteFilteredFiles(final File dir, final FilenameFilter fileNameFilter) {
|
||||
if (!dir.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
final File[] files = dir.listFiles(fileNameFilter);
|
||||
if (files == null) {
|
||||
return false;
|
||||
}
|
||||
boolean hasDeletedAllFiles = true;
|
||||
for (final File file : files) {
|
||||
if (!deleteRecursively(file)) {
|
||||
hasDeletedAllFiles = false;
|
||||
}
|
||||
}
|
||||
return hasDeletedAllFiles;
|
||||
}
|
||||
|
||||
public static boolean renameTo(final File fromFile, final File toFile) {
|
||||
toFile.delete();
|
||||
return fromFile.renameTo(toFile);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
// TODO: This class is not thread-safe.
|
||||
public final class InputPointers {
|
||||
private static final boolean DEBUG_TIME = false;
|
||||
|
||||
private final int mDefaultCapacity;
|
||||
private final ResizableIntArray mXCoordinates;
|
||||
private final ResizableIntArray mYCoordinates;
|
||||
private final ResizableIntArray mPointerIds;
|
||||
private final ResizableIntArray mTimes;
|
||||
|
||||
public InputPointers(final int defaultCapacity) {
|
||||
mDefaultCapacity = defaultCapacity;
|
||||
mXCoordinates = new ResizableIntArray(defaultCapacity);
|
||||
mYCoordinates = new ResizableIntArray(defaultCapacity);
|
||||
mPointerIds = new ResizableIntArray(defaultCapacity);
|
||||
mTimes = new ResizableIntArray(defaultCapacity);
|
||||
}
|
||||
|
||||
private void fillWithLastTimeUntil(final int index) {
|
||||
final int fromIndex = mTimes.getLength();
|
||||
// Fill the gap with the latest time.
|
||||
// See {@link #getTime(int)} and {@link #isValidTimeStamps()}.
|
||||
if (fromIndex <= 0) {
|
||||
return;
|
||||
}
|
||||
final int fillLength = index - fromIndex + 1;
|
||||
if (fillLength <= 0) {
|
||||
return;
|
||||
}
|
||||
final int lastTime = mTimes.get(fromIndex - 1);
|
||||
mTimes.fill(lastTime, fromIndex, fillLength);
|
||||
}
|
||||
|
||||
public void addPointerAt(final int index, final int x, final int y, final int pointerId,
|
||||
final int time) {
|
||||
mXCoordinates.addAt(index, x);
|
||||
mYCoordinates.addAt(index, y);
|
||||
mPointerIds.addAt(index, pointerId);
|
||||
if (DEBUG_TIME) {
|
||||
fillWithLastTimeUntil(index);
|
||||
}
|
||||
mTimes.addAt(index, time);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public void addPointer(final int x, final int y, final int pointerId, final int time) {
|
||||
mXCoordinates.add(x);
|
||||
mYCoordinates.add(y);
|
||||
mPointerIds.add(pointerId);
|
||||
mTimes.add(time);
|
||||
}
|
||||
|
||||
public void set(@Nonnull final InputPointers ip) {
|
||||
mXCoordinates.set(ip.mXCoordinates);
|
||||
mYCoordinates.set(ip.mYCoordinates);
|
||||
mPointerIds.set(ip.mPointerIds);
|
||||
mTimes.set(ip.mTimes);
|
||||
}
|
||||
|
||||
public void copy(@Nonnull final InputPointers ip) {
|
||||
mXCoordinates.copy(ip.mXCoordinates);
|
||||
mYCoordinates.copy(ip.mYCoordinates);
|
||||
mPointerIds.copy(ip.mPointerIds);
|
||||
mTimes.copy(ip.mTimes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray}
|
||||
* to the end of this.
|
||||
* @param pointerId the pointer id of the source.
|
||||
* @param times the source {@link ResizableIntArray} to read the event times from.
|
||||
* @param xCoordinates the source {@link ResizableIntArray} to read the x-coordinates from.
|
||||
* @param yCoordinates the source {@link ResizableIntArray} to read the y-coordinates from.
|
||||
* @param startPos the starting index of the data in {@code times} and etc.
|
||||
* @param length the number of data to be appended.
|
||||
*/
|
||||
public void append(final int pointerId, @Nonnull final ResizableIntArray times,
|
||||
@Nonnull final ResizableIntArray xCoordinates,
|
||||
@Nonnull final ResizableIntArray yCoordinates, final int startPos, final int length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
mXCoordinates.append(xCoordinates, startPos, length);
|
||||
mYCoordinates.append(yCoordinates, startPos, length);
|
||||
mPointerIds.fill(pointerId, mPointerIds.getLength(), length);
|
||||
mTimes.append(times, startPos, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift to the left by elementCount, discarding elementCount pointers at the start.
|
||||
* @param elementCount how many elements to shift.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public void shift(final int elementCount) {
|
||||
mXCoordinates.shift(elementCount);
|
||||
mYCoordinates.shift(elementCount);
|
||||
mPointerIds.shift(elementCount);
|
||||
mTimes.shift(elementCount);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
final int defaultCapacity = mDefaultCapacity;
|
||||
mXCoordinates.reset(defaultCapacity);
|
||||
mYCoordinates.reset(defaultCapacity);
|
||||
mPointerIds.reset(defaultCapacity);
|
||||
mTimes.reset(defaultCapacity);
|
||||
}
|
||||
|
||||
public int getPointerSize() {
|
||||
return mXCoordinates.getLength();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public int[] getXCoordinates() {
|
||||
return mXCoordinates.getPrimitiveArray();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public int[] getYCoordinates() {
|
||||
return mYCoordinates.getPrimitiveArray();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public int[] getPointerIds() {
|
||||
return mPointerIds.getPrimitiveArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time each point was registered, in milliseconds, relative to the first event in the
|
||||
* sequence.
|
||||
* @return The time each point was registered, in milliseconds, relative to the first event in
|
||||
* the sequence.
|
||||
*/
|
||||
@Nonnull
|
||||
public int[] getTimes() {
|
||||
return mTimes.getPrimitiveArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "size=" + getPointerSize() + " id=" + mPointerIds + " time=" + mTimes
|
||||
+ " x=" + mXCoordinates + " y=" + mYCoordinates;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.latin.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A class to help with handling Locales in string form.
|
||||
*
|
||||
* This file has the same meaning and features (and shares all of its code) with the one with the
|
||||
* same name in Latin IME. They need to be kept synchronized; for any update/bugfix to
|
||||
* this file, consider also updating/fixing the version in Latin IME.
|
||||
*/
|
||||
public final class LocaleUtils {
|
||||
private LocaleUtils() {
|
||||
// Intentional empty constructor for utility class.
|
||||
}
|
||||
|
||||
// Locale match level constants.
|
||||
// A higher level of match is guaranteed to have a higher numerical value.
|
||||
// Some room is left within constants to add match cases that may arise necessary
|
||||
// in the future, for example differentiating between the case where the countries
|
||||
// are both present and different, and the case where one of the locales does not
|
||||
// specify the countries. This difference is not needed now.
|
||||
|
||||
// Nothing matches.
|
||||
public static final int LOCALE_NO_MATCH = 0;
|
||||
// The languages matches, but the country are different. Or, the reference locale requires a
|
||||
// country and the tested locale does not have one.
|
||||
public static final int LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER = 3;
|
||||
// The languages and country match, but the variants are different. Or, the reference locale
|
||||
// requires a variant and the tested locale does not have one.
|
||||
public static final int LOCALE_LANGUAGE_AND_COUNTRY_MATCH_VARIANT_DIFFER = 6;
|
||||
// The required locale is null or empty so it will accept anything, and the tested locale
|
||||
// is non-null and non-empty.
|
||||
public static final int LOCALE_ANY_MATCH = 10;
|
||||
// The language matches, and the tested locale specifies a country but the reference locale
|
||||
// does not require one.
|
||||
public static final int LOCALE_LANGUAGE_MATCH = 15;
|
||||
// The language and the country match, and the tested locale specifies a variant but the
|
||||
// reference locale does not require one.
|
||||
public static final int LOCALE_LANGUAGE_AND_COUNTRY_MATCH = 20;
|
||||
// The compared locales are fully identical. This is the best match level.
|
||||
public static final int LOCALE_FULL_MATCH = 30;
|
||||
|
||||
// The level at which a match is "normally" considered a locale match with standard algorithms.
|
||||
// Don't use this directly, use #isMatch to test.
|
||||
private static final int LOCALE_MATCH = LOCALE_ANY_MATCH;
|
||||
|
||||
// Make this match the maximum match level. If this evolves to have more than 2 digits
|
||||
// when written in base 10, also adjust the getMatchLevelSortedString method.
|
||||
private static final int MATCH_LEVEL_MAX = 30;
|
||||
|
||||
/**
|
||||
* Return how well a tested locale matches a reference locale.
|
||||
*
|
||||
* This will check the tested locale against the reference locale and return a measure of how
|
||||
* a well it matches the reference. The general idea is that the tested locale has to match
|
||||
* every specified part of the required locale. A full match occur when they are equal, a
|
||||
* partial match when the tested locale agrees with the reference locale but is more specific,
|
||||
* and a difference when the tested locale does not comply with all requirements from the
|
||||
* reference locale.
|
||||
* In more detail, if the reference locale specifies at least a language and the testedLocale
|
||||
* does not specify one, or specifies a different one, LOCALE_NO_MATCH is returned. If the
|
||||
* reference locale is empty or null, it will match anything - in the form of LOCALE_FULL_MATCH
|
||||
* if the tested locale is empty or null, and LOCALE_ANY_MATCH otherwise. If the reference and
|
||||
* tested locale agree on the language, but not on the country,
|
||||
* LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER is returned if the reference locale specifies a country,
|
||||
* and LOCALE_LANGUAGE_MATCH otherwise.
|
||||
* If they agree on both the language and the country, but not on the variant,
|
||||
* LOCALE_LANGUAGE_AND_COUNTRY_MATCH_VARIANT_DIFFER is returned if the reference locale
|
||||
* specifies a variant, and LOCALE_LANGUAGE_AND_COUNTRY_MATCH otherwise. If everything matches,
|
||||
* LOCALE_FULL_MATCH is returned.
|
||||
* Examples:
|
||||
* en <=> en_US => LOCALE_LANGUAGE_MATCH
|
||||
* en_US <=> en => LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER
|
||||
* en_US_POSIX <=> en_US_Android => LOCALE_LANGUAGE_AND_COUNTRY_MATCH_VARIANT_DIFFER
|
||||
* en_US <=> en_US_Android => LOCALE_LANGUAGE_AND_COUNTRY_MATCH
|
||||
* sp_US <=> en_US => LOCALE_NO_MATCH
|
||||
* de <=> de => LOCALE_FULL_MATCH
|
||||
* en_US <=> en_US => LOCALE_FULL_MATCH
|
||||
* "" <=> en_US => LOCALE_ANY_MATCH
|
||||
*
|
||||
* @param referenceLocale the reference locale to test against.
|
||||
* @param testedLocale the locale to test.
|
||||
* @return a constant that measures how well the tested locale matches the reference locale.
|
||||
*/
|
||||
public static int getMatchLevel(@Nullable final String referenceLocale,
|
||||
@Nullable final String testedLocale) {
|
||||
if (StringUtils.isEmpty(referenceLocale)) {
|
||||
return StringUtils.isEmpty(testedLocale) ? LOCALE_FULL_MATCH : LOCALE_ANY_MATCH;
|
||||
}
|
||||
if (null == testedLocale) return LOCALE_NO_MATCH;
|
||||
final String[] referenceParams = referenceLocale.split("_", 3);
|
||||
final String[] testedParams = testedLocale.split("_", 3);
|
||||
// By spec of String#split, [0] cannot be null and length cannot be 0.
|
||||
if (!referenceParams[0].equals(testedParams[0])) return LOCALE_NO_MATCH;
|
||||
switch (referenceParams.length) {
|
||||
case 1:
|
||||
return 1 == testedParams.length ? LOCALE_FULL_MATCH : LOCALE_LANGUAGE_MATCH;
|
||||
case 2:
|
||||
if (1 == testedParams.length) return LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER;
|
||||
if (!referenceParams[1].equals(testedParams[1]))
|
||||
return LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER;
|
||||
if (3 == testedParams.length) return LOCALE_LANGUAGE_AND_COUNTRY_MATCH;
|
||||
return LOCALE_FULL_MATCH;
|
||||
case 3:
|
||||
if (1 == testedParams.length) return LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER;
|
||||
if (!referenceParams[1].equals(testedParams[1]))
|
||||
return LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER;
|
||||
if (2 == testedParams.length) return LOCALE_LANGUAGE_AND_COUNTRY_MATCH_VARIANT_DIFFER;
|
||||
if (!referenceParams[2].equals(testedParams[2]))
|
||||
return LOCALE_LANGUAGE_AND_COUNTRY_MATCH_VARIANT_DIFFER;
|
||||
return LOCALE_FULL_MATCH;
|
||||
}
|
||||
// It should be impossible to come here
|
||||
return LOCALE_NO_MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string that represents this match level, with better matches first.
|
||||
*
|
||||
* The strings are sorted in lexicographic order: a better match will always be less than
|
||||
* a worse match when compared together.
|
||||
*/
|
||||
public static String getMatchLevelSortedString(final int matchLevel) {
|
||||
// This works because the match levels are 0~99 (actually 0~30)
|
||||
// Ideally this should use a number of digits equals to the 1og10 of the greater matchLevel
|
||||
return String.format(Locale.ROOT, "%02d", MATCH_LEVEL_MAX - matchLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether a match level should be considered a match.
|
||||
*
|
||||
* This method takes a match level as returned by the #getMatchLevel method, and returns whether
|
||||
* it should be considered a match in the usual sense with standard Locale functions.
|
||||
*
|
||||
* @param level the match level, as returned by getMatchLevel.
|
||||
* @return whether this is a match or not.
|
||||
*/
|
||||
public static boolean isMatch(final int level) {
|
||||
return LOCALE_MATCH <= level;
|
||||
}
|
||||
|
||||
private static final HashMap<String, Locale> sLocaleCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a locale from a string specification.
|
||||
* @param localeString a string specification of a locale, in a format of "ll_cc_variant" where
|
||||
* "ll" is a language code, "cc" is a country code.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Locale constructLocaleFromString(@Nonnull final String localeString) {
|
||||
synchronized (sLocaleCache) {
|
||||
if (sLocaleCache.containsKey(localeString)) {
|
||||
return sLocaleCache.get(localeString);
|
||||
}
|
||||
final String[] elements = localeString.split("_", 3);
|
||||
final Locale locale;
|
||||
if (elements.length == 1) {
|
||||
locale = new Locale(elements[0] /* language */);
|
||||
} else if (elements.length == 2) {
|
||||
locale = new Locale(elements[0] /* language */, elements[1] /* country */);
|
||||
} else { // localeParams.length == 3
|
||||
locale = new Locale(elements[0] /* language */, elements[1] /* country */,
|
||||
elements[2] /* variant */);
|
||||
}
|
||||
sLocaleCache.put(localeString, locale);
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Get this information from the framework instead of maintaining here by ourselves.
|
||||
private static final HashSet<String> sRtlLanguageCodes = new HashSet<>();
|
||||
static {
|
||||
// List of known Right-To-Left language codes.
|
||||
sRtlLanguageCodes.add("ar"); // Arabic
|
||||
sRtlLanguageCodes.add("fa"); // Persian
|
||||
sRtlLanguageCodes.add("iw"); // Hebrew
|
||||
sRtlLanguageCodes.add("ku"); // Kurdish
|
||||
sRtlLanguageCodes.add("ps"); // Pashto
|
||||
sRtlLanguageCodes.add("sd"); // Sindhi
|
||||
sRtlLanguageCodes.add("ug"); // Uyghur
|
||||
sRtlLanguageCodes.add("ur"); // Urdu
|
||||
sRtlLanguageCodes.add("yi"); // Yiddish
|
||||
}
|
||||
|
||||
public static boolean isRtlLanguage(@Nonnull final Locale locale) {
|
||||
return sRtlLanguageCodes.contains(locale.getLanguage());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.latin.common;
|
||||
|
||||
public class NativeSuggestOptions {
|
||||
// Need to update suggest_options.h when you add, remove or reorder options.
|
||||
private static final int IS_GESTURE = 0;
|
||||
private static final int USE_FULL_EDIT_DISTANCE = 1;
|
||||
private static final int BLOCK_OFFENSIVE_WORDS = 2;
|
||||
private static final int SPACE_AWARE_GESTURE_ENABLED = 3;
|
||||
private static final int WEIGHT_FOR_LOCALE_IN_THOUSANDS = 4;
|
||||
private static final int OPTIONS_SIZE = 5;
|
||||
|
||||
private final int[] mOptions;
|
||||
|
||||
public NativeSuggestOptions() {
|
||||
mOptions = new int[OPTIONS_SIZE];
|
||||
}
|
||||
|
||||
public void setIsGesture(final boolean value) {
|
||||
setBooleanOption(IS_GESTURE, value);
|
||||
}
|
||||
|
||||
public void setUseFullEditDistance(final boolean value) {
|
||||
setBooleanOption(USE_FULL_EDIT_DISTANCE, value);
|
||||
}
|
||||
|
||||
public void setBlockOffensiveWords(final boolean value) {
|
||||
setBooleanOption(BLOCK_OFFENSIVE_WORDS, value);
|
||||
}
|
||||
|
||||
public void setWeightForLocale(final float value) {
|
||||
// We're passing this option as a fixed point value, in thousands. This is decoded in
|
||||
// native code by SuggestOptions#weightForLocale().
|
||||
setIntegerOption(WEIGHT_FOR_LOCALE_IN_THOUSANDS, (int) (value * 1000));
|
||||
}
|
||||
|
||||
public int[] getOptions() {
|
||||
return mOptions;
|
||||
}
|
||||
|
||||
private void setBooleanOption(final int key, final boolean value) {
|
||||
mOptions[key] = value ? 1 : 0;
|
||||
}
|
||||
|
||||
private void setIntegerOption(final int key, final int value) {
|
||||
mOptions[key] = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
// TODO: This class is not thread-safe.
|
||||
public final class ResizableIntArray {
|
||||
@Nonnull
|
||||
private int[] mArray;
|
||||
private int mLength;
|
||||
|
||||
public ResizableIntArray(final int capacity) {
|
||||
reset(capacity);
|
||||
}
|
||||
|
||||
public int get(final int index) {
|
||||
if (index < mLength) {
|
||||
return mArray[index];
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index);
|
||||
}
|
||||
|
||||
public void addAt(final int index, final int val) {
|
||||
if (index < mLength) {
|
||||
mArray[index] = val;
|
||||
} else {
|
||||
mLength = index;
|
||||
add(val);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(final int val) {
|
||||
final int currentLength = mLength;
|
||||
ensureCapacity(currentLength + 1);
|
||||
mArray[currentLength] = val;
|
||||
mLength = currentLength + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the new capacity of {@code mArray}.
|
||||
* @param minimumCapacity the minimum capacity that the {@code mArray} should have.
|
||||
* @return the new capacity that the {@code mArray} should have. Returns zero when there is no
|
||||
* need to expand {@code mArray}.
|
||||
*/
|
||||
private int calculateCapacity(final int minimumCapacity) {
|
||||
final int currentCapcity = mArray.length;
|
||||
if (currentCapcity < minimumCapacity) {
|
||||
final int nextCapacity = currentCapcity * 2;
|
||||
// The following is the same as return Math.max(minimumCapacity, nextCapacity);
|
||||
return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void ensureCapacity(final int minimumCapacity) {
|
||||
final int newCapacity = calculateCapacity(minimumCapacity);
|
||||
if (newCapacity > 0) {
|
||||
// TODO: Implement primitive array pool.
|
||||
mArray = Arrays.copyOf(mArray, newCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public void setLength(final int newLength) {
|
||||
ensureCapacity(newLength);
|
||||
mLength = newLength;
|
||||
}
|
||||
|
||||
public void reset(final int capacity) {
|
||||
// TODO: Implement primitive array pool.
|
||||
mArray = new int[capacity];
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public int[] getPrimitiveArray() {
|
||||
return mArray;
|
||||
}
|
||||
|
||||
public void set(@Nonnull final ResizableIntArray ip) {
|
||||
// TODO: Implement primitive array pool.
|
||||
mArray = ip.mArray;
|
||||
mLength = ip.mLength;
|
||||
}
|
||||
|
||||
public void copy(@Nonnull final ResizableIntArray ip) {
|
||||
final int newCapacity = calculateCapacity(ip.mLength);
|
||||
if (newCapacity > 0) {
|
||||
// TODO: Implement primitive array pool.
|
||||
mArray = new int[newCapacity];
|
||||
}
|
||||
System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
|
||||
mLength = ip.mLength;
|
||||
}
|
||||
|
||||
public void append(@Nonnull final ResizableIntArray src, final int startPos, final int length) {
|
||||
if (length == 0) {
|
||||
return;
|
||||
}
|
||||
final int currentLength = mLength;
|
||||
final int newLength = currentLength + length;
|
||||
ensureCapacity(newLength);
|
||||
System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
|
||||
mLength = newLength;
|
||||
}
|
||||
|
||||
public void fill(final int value, final int startPos, final int length) {
|
||||
if (startPos < 0 || length < 0) {
|
||||
throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length);
|
||||
}
|
||||
final int endPos = startPos + length;
|
||||
ensureCapacity(endPos);
|
||||
Arrays.fill(mArray, startPos, endPos, value);
|
||||
if (mLength < endPos) {
|
||||
mLength = endPos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift to the left by elementCount, discarding elementCount pointers at the start.
|
||||
* @param elementCount how many elements to shift.
|
||||
*/
|
||||
@UsedForTesting
|
||||
public void shift(final int elementCount) {
|
||||
System.arraycopy(mArray, elementCount, mArray, 0, mLength - elementCount);
|
||||
mLength -= elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < mLength; i++) {
|
||||
if (i != 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(mArray[i]);
|
||||
}
|
||||
return "[" + sb + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,704 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.common;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class StringUtils {
|
||||
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
|
||||
public static final int CAPITALIZE_FIRST = 1; // First only
|
||||
public static final int CAPITALIZE_ALL = 2; // All caps
|
||||
|
||||
@Nonnull
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
private static final char CHAR_LINE_FEED = 0X000A;
|
||||
private static final char CHAR_VERTICAL_TAB = 0X000B;
|
||||
private static final char CHAR_FORM_FEED = 0X000C;
|
||||
private static final char CHAR_CARRIAGE_RETURN = 0X000D;
|
||||
private static final char CHAR_NEXT_LINE = 0X0085;
|
||||
private static final char CHAR_LINE_SEPARATOR = 0X2028;
|
||||
private static final char CHAR_PARAGRAPH_SEPARATOR = 0X2029;
|
||||
|
||||
private StringUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
// Taken from android.text.TextUtils. We are extensively using this method in many places,
|
||||
// some of which don't have the android libraries available.
|
||||
/**
|
||||
* Returns true if the string is null or 0-length.
|
||||
* @param str the string to be examined
|
||||
* @return true if str is null or zero length
|
||||
*/
|
||||
public static boolean isEmpty(@Nullable final CharSequence str) {
|
||||
return (str == null || str.length() == 0);
|
||||
}
|
||||
|
||||
// Taken from android.text.TextUtils to cut the dependency to the Android framework.
|
||||
/**
|
||||
* Returns a string containing the tokens joined by delimiters.
|
||||
* @param delimiter the delimiter
|
||||
* @param tokens an array objects to be joined. Strings will be formed from
|
||||
* the objects by calling object.toString().
|
||||
*/
|
||||
@Nonnull
|
||||
public static String join(@Nonnull final CharSequence delimiter,
|
||||
@Nonnull final Iterable<?> tokens) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean firstTime = true;
|
||||
for (final Object token: tokens) {
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
} else {
|
||||
sb.append(delimiter);
|
||||
}
|
||||
sb.append(token);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// Taken from android.text.TextUtils to cut the dependency to the Android framework.
|
||||
/**
|
||||
* Returns true if a and b are equal, including if they are both null.
|
||||
* <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if
|
||||
* both the arguments were instances of String.</i></p>
|
||||
* @param a first CharSequence to check
|
||||
* @param b second CharSequence to check
|
||||
* @return true if a and b are equal
|
||||
*/
|
||||
public static boolean equals(@Nullable final CharSequence a, @Nullable final CharSequence b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
final int length;
|
||||
if (a != null && b != null && (length = a.length()) == b.length()) {
|
||||
if (a instanceof String && b instanceof String) {
|
||||
return a.equals(b);
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (a.charAt(i) != b.charAt(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int codePointCount(@Nullable final CharSequence text) {
|
||||
if (isEmpty(text)) {
|
||||
return 0;
|
||||
}
|
||||
return Character.codePointCount(text, 0, text.length());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String newSingleCodePointString(final int codePoint) {
|
||||
if (Character.charCount(codePoint) == 1) {
|
||||
// Optimization: avoid creating a temporary array for characters that are
|
||||
// represented by a single char value
|
||||
return String.valueOf((char) codePoint);
|
||||
}
|
||||
// For surrogate pair
|
||||
return new String(Character.toChars(codePoint));
|
||||
}
|
||||
|
||||
public static boolean containsInArray(@Nonnull final String text,
|
||||
@Nonnull final String[] array) {
|
||||
for (final String element : array) {
|
||||
if (text.equals(element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comma-Splittable Text is similar to Comma-Separated Values (CSV) but has much simpler syntax.
|
||||
* Unlike CSV, Comma-Splittable Text has no escaping mechanism, so that the text can't contain
|
||||
* a comma character in it.
|
||||
*/
|
||||
@Nonnull
|
||||
private static final String SEPARATOR_FOR_COMMA_SPLITTABLE_TEXT = ",";
|
||||
|
||||
public static boolean containsInCommaSplittableText(@Nonnull final String text,
|
||||
@Nullable final String extraValues) {
|
||||
if (isEmpty(extraValues)) {
|
||||
return false;
|
||||
}
|
||||
return containsInArray(text, extraValues.split(SEPARATOR_FOR_COMMA_SPLITTABLE_TEXT));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String removeFromCommaSplittableTextIfExists(@Nonnull final String text,
|
||||
@Nullable final String extraValues) {
|
||||
if (isEmpty(extraValues)) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
final String[] elements = extraValues.split(SEPARATOR_FOR_COMMA_SPLITTABLE_TEXT);
|
||||
if (!containsInArray(text, elements)) {
|
||||
return extraValues;
|
||||
}
|
||||
final ArrayList<String> result = new ArrayList<>(elements.length - 1);
|
||||
for (final String element : elements) {
|
||||
if (!text.equals(element)) {
|
||||
result.add(element);
|
||||
}
|
||||
}
|
||||
return join(SEPARATOR_FOR_COMMA_SPLITTABLE_TEXT, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicates from an array of strings.
|
||||
*
|
||||
* This method will always keep the first occurrence of all strings at their position
|
||||
* in the array, removing the subsequent ones.
|
||||
*/
|
||||
public static void removeDupes(@Nonnull final ArrayList<String> suggestions) {
|
||||
if (suggestions.size() < 2) {
|
||||
return;
|
||||
}
|
||||
int i = 1;
|
||||
// Don't cache suggestions.size(), since we may be removing items
|
||||
while (i < suggestions.size()) {
|
||||
final String cur = suggestions.get(i);
|
||||
// Compare each suggestion with each previous suggestion
|
||||
for (int j = 0; j < i; j++) {
|
||||
final String previous = suggestions.get(j);
|
||||
if (equals(cur, previous)) {
|
||||
suggestions.remove(i);
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String capitalizeFirstCodePoint(@Nonnull final String s,
|
||||
@Nonnull final Locale locale) {
|
||||
if (s.length() <= 1) {
|
||||
return s.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
// Please refer to the comment below in
|
||||
// {@link #capitalizeFirstAndDowncaseRest(String,Locale)} as this has the same shortcomings
|
||||
final int cutoff = s.offsetByCodePoints(0, 1);
|
||||
return s.substring(0, cutoff).toUpperCase(getLocaleUsedForToTitleCase(locale))
|
||||
+ s.substring(cutoff);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String capitalizeFirstAndDowncaseRest(@Nonnull final String s,
|
||||
@Nonnull final Locale locale) {
|
||||
if (s.length() <= 1) {
|
||||
return s.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
// TODO: fix the bugs below
|
||||
// - It does not work for Serbian, because it fails to account for the "lj" character,
|
||||
// which should be "Lj" in title case and "LJ" in upper case.
|
||||
// - It does not work for Dutch, because it fails to account for the "ij" digraph when it's
|
||||
// written as two separate code points. They are two different characters but both should
|
||||
// be capitalized as "IJ" as if they were a single letter in most words (not all). If the
|
||||
// unicode char for the ligature is used however, it works.
|
||||
final int cutoff = s.offsetByCodePoints(0, 1);
|
||||
return s.substring(0, cutoff).toUpperCase(getLocaleUsedForToTitleCase(locale))
|
||||
+ s.substring(cutoff).toLowerCase(locale);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] toCodePointArray(@Nonnull final CharSequence charSequence) {
|
||||
return toCodePointArray(charSequence, 0, charSequence.length());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static final int[] EMPTY_CODEPOINTS = {};
|
||||
|
||||
/**
|
||||
* Converts a range of a string to an array of code points.
|
||||
* @param charSequence the source string.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @return a new array of code points. At most endIndex - startIndex, but possibly less.
|
||||
*/
|
||||
@Nonnull
|
||||
public static int[] toCodePointArray(@Nonnull final CharSequence charSequence,
|
||||
final int startIndex, final int endIndex) {
|
||||
final int length = charSequence.length();
|
||||
if (length <= 0) {
|
||||
return EMPTY_CODEPOINTS;
|
||||
}
|
||||
final int[] codePoints =
|
||||
new int[Character.codePointCount(charSequence, startIndex, endIndex)];
|
||||
copyCodePointsAndReturnCodePointCount(codePoints, charSequence, startIndex, endIndex,
|
||||
false /* downCase */);
|
||||
return codePoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the codepoints in a CharSequence to an int array.
|
||||
*
|
||||
* This method assumes there is enough space in the array to store the code points. The size
|
||||
* can be measured with Character#codePointCount(CharSequence, int, int) before passing to this
|
||||
* method. If the int array is too small, an ArrayIndexOutOfBoundsException will be thrown.
|
||||
* Also, this method makes no effort to be thread-safe. Do not modify the CharSequence while
|
||||
* this method is running, or the behavior is undefined.
|
||||
* This method can optionally downcase code points before copying them, but it pays no attention
|
||||
* to locale while doing so.
|
||||
*
|
||||
* @param destination the int array.
|
||||
* @param charSequence the CharSequence.
|
||||
* @param startIndex the start index inside the string in java chars, inclusive.
|
||||
* @param endIndex the end index inside the string in java chars, exclusive.
|
||||
* @param downCase if this is true, code points will be downcased before being copied.
|
||||
* @return the number of copied code points.
|
||||
*/
|
||||
public static int copyCodePointsAndReturnCodePointCount(@Nonnull final int[] destination,
|
||||
@Nonnull final CharSequence charSequence, final int startIndex, final int endIndex,
|
||||
final boolean downCase) {
|
||||
int destIndex = 0;
|
||||
for (int index = startIndex; index < endIndex;
|
||||
index = Character.offsetByCodePoints(charSequence, index, 1)) {
|
||||
final int codePoint = Character.codePointAt(charSequence, index);
|
||||
// TODO: stop using this, as it's not aware of the locale and does not always do
|
||||
// the right thing.
|
||||
destination[destIndex] = downCase ? Character.toLowerCase(codePoint) : codePoint;
|
||||
destIndex++;
|
||||
}
|
||||
return destIndex;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static int[] toSortedCodePointArray(@Nonnull final String string) {
|
||||
final int[] codePoints = toCodePointArray(string);
|
||||
Arrays.sort(codePoints);
|
||||
return codePoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a String from a code point array
|
||||
*
|
||||
* @param codePoints a code point array that is null terminated when its logical length is
|
||||
* shorter than the array length.
|
||||
* @return a string constructed from the code point array.
|
||||
*/
|
||||
@Nonnull
|
||||
public static String getStringFromNullTerminatedCodePointArray(
|
||||
@Nonnull final int[] codePoints) {
|
||||
int stringLength = codePoints.length;
|
||||
for (int i = 0; i < codePoints.length; i++) {
|
||||
if (codePoints[i] == 0) {
|
||||
stringLength = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new String(codePoints, 0 /* offset */, stringLength);
|
||||
}
|
||||
|
||||
// This method assumes the text is not null. For the empty string, it returns CAPITALIZE_NONE.
|
||||
public static int getCapitalizationType(@Nonnull final String text) {
|
||||
// If the first char is not uppercase, then the word is either all lower case or
|
||||
// camel case, and in either case we return CAPITALIZE_NONE.
|
||||
final int len = text.length();
|
||||
int index = 0;
|
||||
for (; index < len; index = text.offsetByCodePoints(index, 1)) {
|
||||
if (Character.isLetter(text.codePointAt(index))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == len) return CAPITALIZE_NONE;
|
||||
if (!Character.isUpperCase(text.codePointAt(index))) {
|
||||
return CAPITALIZE_NONE;
|
||||
}
|
||||
int capsCount = 1;
|
||||
int letterCount = 1;
|
||||
for (index = text.offsetByCodePoints(index, 1); index < len;
|
||||
index = text.offsetByCodePoints(index, 1)) {
|
||||
if (1 != capsCount && letterCount != capsCount) break;
|
||||
final int codePoint = text.codePointAt(index);
|
||||
if (Character.isUpperCase(codePoint)) {
|
||||
++capsCount;
|
||||
++letterCount;
|
||||
} else if (Character.isLetter(codePoint)) {
|
||||
// We need to discount non-letters since they may not be upper-case, but may
|
||||
// still be part of a word (e.g. single quote or dash, as in "IT'S" or "FULL-TIME")
|
||||
++letterCount;
|
||||
}
|
||||
}
|
||||
// We know the first char is upper case. So we want to test if either every letter other
|
||||
// than the first is lower case, or if they are all upper case. If the string is exactly
|
||||
// one char long, then we will arrive here with letterCount 1, and this is correct, too.
|
||||
if (1 == capsCount) return CAPITALIZE_FIRST;
|
||||
return (letterCount == capsCount ? CAPITALIZE_ALL : CAPITALIZE_NONE);
|
||||
}
|
||||
|
||||
public static boolean isIdenticalAfterUpcase(@Nonnull final String text) {
|
||||
final int length = text.length();
|
||||
int i = 0;
|
||||
while (i < length) {
|
||||
final int codePoint = text.codePointAt(i);
|
||||
if (Character.isLetter(codePoint) && !Character.isUpperCase(codePoint)) {
|
||||
return false;
|
||||
}
|
||||
i += Character.charCount(codePoint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isIdenticalAfterDowncase(@Nonnull final String text) {
|
||||
final int length = text.length();
|
||||
int i = 0;
|
||||
while (i < length) {
|
||||
final int codePoint = text.codePointAt(i);
|
||||
if (Character.isLetter(codePoint) && !Character.isLowerCase(codePoint)) {
|
||||
return false;
|
||||
}
|
||||
i += Character.charCount(codePoint);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isIdenticalAfterCapitalizeEachWord(@Nonnull final String text,
|
||||
@Nonnull final int[] sortedSeparators) {
|
||||
boolean needsCapsNext = true;
|
||||
final int len = text.length();
|
||||
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
|
||||
final int codePoint = text.codePointAt(i);
|
||||
if (Character.isLetter(codePoint)) {
|
||||
if ((needsCapsNext && !Character.isUpperCase(codePoint))
|
||||
|| (!needsCapsNext && !Character.isLowerCase(codePoint))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// We need a capital letter next if this is a separator.
|
||||
needsCapsNext = (Arrays.binarySearch(sortedSeparators, codePoint) >= 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: like capitalizeFirst*, this does not work perfectly for Dutch because of the IJ digraph
|
||||
// which should be capitalized together in *some* cases.
|
||||
@Nonnull
|
||||
public static String capitalizeEachWord(@Nonnull final String text,
|
||||
@Nonnull final int[] sortedSeparators, @Nonnull final Locale locale) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
boolean needsCapsNext = true;
|
||||
final int len = text.length();
|
||||
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
|
||||
final String nextChar = text.substring(i, text.offsetByCodePoints(i, 1));
|
||||
if (needsCapsNext) {
|
||||
builder.append(nextChar.toUpperCase(locale));
|
||||
} else {
|
||||
builder.append(nextChar.toLowerCase(locale));
|
||||
}
|
||||
// We need a capital letter next if this is a separator.
|
||||
needsCapsNext = (Arrays.binarySearch(sortedSeparators, nextChar.codePointAt(0)) >= 0);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Approximates whether the text before the cursor looks like a URL.
|
||||
*
|
||||
* This is not foolproof, but it should work well in the practice.
|
||||
* Essentially it walks backward from the cursor until it finds something that's not a letter,
|
||||
* digit, or common URL symbol like underscore. If it hasn't found a period yet, then it
|
||||
* does not look like a URL.
|
||||
* If the text:
|
||||
* - starts with www and contains a period
|
||||
* - starts with a slash preceded by either a slash, whitespace, or start-of-string
|
||||
* Then it looks like a URL and we return true. Otherwise, we return false.
|
||||
*
|
||||
* Note: this method is called quite often, and should be fast.
|
||||
*
|
||||
* TODO: This will return that "abc./def" and ".abc/def" look like URLs to keep down the
|
||||
* code complexity, but ideally it should not. It's acceptable for now.
|
||||
*/
|
||||
public static boolean lastPartLooksLikeURL(@Nonnull final CharSequence text) {
|
||||
int i = text.length();
|
||||
if (0 == i) {
|
||||
return false;
|
||||
}
|
||||
int wCount = 0;
|
||||
int slashCount = 0;
|
||||
boolean hasSlash = false;
|
||||
boolean hasPeriod = false;
|
||||
int codePoint = 0;
|
||||
while (i > 0) {
|
||||
codePoint = Character.codePointBefore(text, i);
|
||||
if (codePoint < Constants.CODE_PERIOD || codePoint > 'z') {
|
||||
// Handwavy heuristic to see if that's a URL character. Anything between period
|
||||
// and z. This includes all lower- and upper-case ascii letters, period,
|
||||
// underscore, arrobase, question mark, equal sign. It excludes spaces, exclamation
|
||||
// marks, double quotes...
|
||||
// Anything that's not a URL-like character causes us to break from here and
|
||||
// evaluate normally.
|
||||
break;
|
||||
}
|
||||
if (Constants.CODE_PERIOD == codePoint) {
|
||||
hasPeriod = true;
|
||||
}
|
||||
if (Constants.CODE_SLASH == codePoint) {
|
||||
hasSlash = true;
|
||||
if (2 == ++slashCount) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
slashCount = 0;
|
||||
}
|
||||
if ('w' == codePoint) {
|
||||
++wCount;
|
||||
} else {
|
||||
wCount = 0;
|
||||
}
|
||||
i = Character.offsetByCodePoints(text, i, -1);
|
||||
}
|
||||
// End of the text run.
|
||||
// If it starts with www and includes a period, then it looks like a URL.
|
||||
if (wCount >= 3 && hasPeriod) {
|
||||
return true;
|
||||
}
|
||||
// If it starts with a slash, and the code point before is whitespace, it looks like an URL.
|
||||
if (1 == slashCount && (0 == i || Character.isWhitespace(codePoint))) {
|
||||
return true;
|
||||
}
|
||||
// If it has both a period and a slash, it looks like an URL.
|
||||
if (hasPeriod && hasSlash) {
|
||||
return true;
|
||||
}
|
||||
// Otherwise, it doesn't look like an URL.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Examines the string and returns whether we're inside a double quote.
|
||||
*
|
||||
* This is used to decide whether we should put an automatic space before or after a double
|
||||
* quote character. If we're inside a quotation, then we want to close it, so we want a space
|
||||
* after and not before. Otherwise, we want to open the quotation, so we want a space before
|
||||
* and not after. Exception: after a digit, we never want a space because the "inch" or
|
||||
* "minutes" use cases is dominant after digits.
|
||||
* In the practice, we determine whether we are in a quotation or not by finding the previous
|
||||
* double quote character, and looking at whether it's followed by whitespace. If so, that
|
||||
* was a closing quotation mark, so we're not inside a double quote. If it's not followed
|
||||
* by whitespace, then it was an opening quotation mark, and we're inside a quotation.
|
||||
*
|
||||
* @param text the text to examine.
|
||||
* @return whether we're inside a double quote.
|
||||
*/
|
||||
public static boolean isInsideDoubleQuoteOrAfterDigit(@Nonnull final CharSequence text) {
|
||||
int i = text.length();
|
||||
if (0 == i) {
|
||||
return false;
|
||||
}
|
||||
int codePoint = Character.codePointBefore(text, i);
|
||||
if (Character.isDigit(codePoint)) {
|
||||
return true;
|
||||
}
|
||||
int prevCodePoint = 0;
|
||||
while (i > 0) {
|
||||
codePoint = Character.codePointBefore(text, i);
|
||||
if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
|
||||
// If we see a double quote followed by whitespace, then that
|
||||
// was a closing quote.
|
||||
if (Character.isWhitespace(prevCodePoint)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Character.isWhitespace(codePoint) && Constants.CODE_DOUBLE_QUOTE == prevCodePoint) {
|
||||
// If we see a double quote preceded by whitespace, then that
|
||||
// was an opening quote. No need to continue seeking.
|
||||
return true;
|
||||
}
|
||||
i -= Character.charCount(codePoint);
|
||||
prevCodePoint = codePoint;
|
||||
}
|
||||
// We reached the start of text. If the first char is a double quote, then we're inside
|
||||
// a double quote. Otherwise we're not.
|
||||
return Constants.CODE_DOUBLE_QUOTE == codePoint;
|
||||
}
|
||||
|
||||
public static boolean isEmptyStringOrWhiteSpaces(@Nonnull final String s) {
|
||||
final int N = codePointCount(s);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (!Character.isWhitespace(s.codePointAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
@Nonnull
|
||||
public static String byteArrayToHexString(@Nullable final byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final byte b : bytes) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex string to byte array. The string length must be an even number.
|
||||
*/
|
||||
@UsedForTesting
|
||||
@Nullable
|
||||
public static byte[] hexStringToByteArray(@Nullable final String hexString) {
|
||||
if (isEmpty(hexString)) {
|
||||
return null;
|
||||
}
|
||||
final int N = hexString.length();
|
||||
if (N % 2 != 0) {
|
||||
throw new NumberFormatException("Input hex string length must be an even number."
|
||||
+ " Length = " + N);
|
||||
}
|
||||
final byte[] bytes = new byte[N / 2];
|
||||
for (int i = 0; i < N; i += 2) {
|
||||
bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
||||
+ Character.digit(hexString.charAt(i + 1), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static final String LANGUAGE_GREEK = "el";
|
||||
|
||||
@Nonnull
|
||||
private static Locale getLocaleUsedForToTitleCase(@Nonnull final Locale locale) {
|
||||
// In Greek locale {@link String#toUpperCase(Locale)} eliminates accents from its result.
|
||||
// In order to get accented upper case letter, {@link Locale#ROOT} should be used.
|
||||
if (LANGUAGE_GREEK.equals(locale.getLanguage())) {
|
||||
return Locale.ROOT;
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String toTitleCaseOfKeyLabel(@Nullable final String label,
|
||||
@Nonnull final Locale locale) {
|
||||
if (label == null) {
|
||||
return label;
|
||||
}
|
||||
return label.toUpperCase(getLocaleUsedForToTitleCase(locale));
|
||||
}
|
||||
|
||||
public static int toTitleCaseOfKeyCode(final int code, @Nonnull final Locale locale) {
|
||||
if (!Constants.isLetterCode(code)) {
|
||||
return code;
|
||||
}
|
||||
final String label = newSingleCodePointString(code);
|
||||
final String titleCaseLabel = toTitleCaseOfKeyLabel(label, locale);
|
||||
return codePointCount(titleCaseLabel) == 1
|
||||
? titleCaseLabel.codePointAt(0) : Constants.CODE_UNSPECIFIED;
|
||||
}
|
||||
|
||||
public static int getTrailingSingleQuotesCount(@Nonnull final CharSequence charSequence) {
|
||||
final int lastIndex = charSequence.length() - 1;
|
||||
int i = lastIndex;
|
||||
while (i >= 0 && charSequence.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
|
||||
--i;
|
||||
}
|
||||
return lastIndex - i;
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public static class Stringizer<E> {
|
||||
@Nonnull
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
@UsedForTesting
|
||||
@Nonnull
|
||||
public String stringize(@Nullable final E element) {
|
||||
if (element == null) {
|
||||
return "null";
|
||||
}
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
@Nonnull
|
||||
public final String join(@Nullable final E[] array) {
|
||||
return joinStringArray(toStringArray(array), null /* delimiter */);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public final String join(@Nullable final E[] array, @Nullable final String delimiter) {
|
||||
return joinStringArray(toStringArray(array), delimiter);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
protected String[] toStringArray(@Nullable final E[] array) {
|
||||
if (array == null) {
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
final String[] stringArray = new String[array.length];
|
||||
for (int index = 0; index < array.length; index++) {
|
||||
stringArray[index] = stringize(array[index]);
|
||||
}
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
protected String joinStringArray(@Nonnull final String[] stringArray,
|
||||
@Nullable final String delimiter) {
|
||||
if (delimiter == null) {
|
||||
return Arrays.toString(stringArray);
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int index = 0; index < stringArray.length; index++) {
|
||||
sb.append(index == 0 ? "[" : delimiter);
|
||||
sb.append(stringArray[index]);
|
||||
}
|
||||
return sb + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the last composed word contains line-breaking character (e.g. CR or LF).
|
||||
* @param text the text to be examined.
|
||||
* @return {@code true} if the last composed word contains line-breaking separator.
|
||||
*/
|
||||
public static boolean hasLineBreakCharacter(@Nullable final String text) {
|
||||
if (isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = text.length() - 1; i >= 0; --i) {
|
||||
final char c = text.charAt(i);
|
||||
switch (c) {
|
||||
case CHAR_LINE_FEED:
|
||||
case CHAR_VERTICAL_TAB:
|
||||
case CHAR_FORM_FEED:
|
||||
case CHAR_CARRIAGE_RETURN:
|
||||
case CHAR_NEXT_LINE:
|
||||
case CHAR_LINE_SEPARATOR:
|
||||
case CHAR_PARAGRAPH_SEPARATOR:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2015 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.latin.common;
|
||||
|
||||
/**
|
||||
* Emojis are supplementary characters expressed as a low+high pair. For instance,
|
||||
* the emoji U+1F625 is encoded as "\uD83D\uDE25" in UTF-16, where '\uD83D' is in
|
||||
* the range of [0xd800, 0xdbff] and '\uDE25' is in the range of [0xdc00, 0xdfff].
|
||||
* {@see http://docs.oracle.com/javase/6/docs/api/java/lang/Character.html#unicode}
|
||||
*/
|
||||
public final class UnicodeSurrogate {
|
||||
private static final char LOW_SURROGATE_MIN = '\uD800';
|
||||
private static final char LOW_SURROGATE_MAX = '\uDBFF';
|
||||
private static final char HIGH_SURROGATE_MIN = '\uDC00';
|
||||
private static final char HIGH_SURROGATE_MAX = '\uDFFF';
|
||||
|
||||
public static boolean isLowSurrogate(final char c) {
|
||||
return c >= LOW_SURROGATE_MIN && c <= LOW_SURROGATE_MAX;
|
||||
}
|
||||
|
||||
public static boolean isHighSurrogate(final char c) {
|
||||
return c >= HIGH_SURROGATE_MIN && c <= HIGH_SURROGATE_MAX;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
# This is a sample wordlist that can be converted to a binary dictionary
|
||||
# for use by the Latin IME.
|
||||
# The file is essentially a CSV file, with indent level denoting nesting.
|
||||
#
|
||||
# The file starts with a single CSV line with the header attributes. Whatever
|
||||
# the content, these are included as is in the binary file. The first attribute
|
||||
# of the file should be `dictionary'. Usual fields are `locale', `description',
|
||||
# `date', `version', `options'.
|
||||
#
|
||||
# Each word has a `word' entry and at least a `f' argument denoting its
|
||||
# probability, as an integer between 0 and 255 on a logarithmic scale, with
|
||||
# 255 meaning 1 and each decrement in 1 dividing probability by 1.15.
|
||||
# As a special case, a weight of 0 is taken to mean profanity - words that
|
||||
# should not be considered a typo, but that should never be suggested
|
||||
# explicitly. An entry may be made not a word by adding a `not_a_word'
|
||||
# field with a value of `true'. The main reason for putting such entries
|
||||
# into the dictionary is to add shortcut targets and maybe a whitelist
|
||||
# replacement.
|
||||
#
|
||||
# Each word may or may not have any number of shortcut target lines
|
||||
# starting with a `shortcut' entry and having at least a `f' frequency
|
||||
# value between 0 and 14, or the special value `whitelist' which becomes
|
||||
# 15, which is then taken to be the whitelist target of this word.
|
||||
#
|
||||
# Each word may also have any number of bigram lines starting with a
|
||||
# `bigram' entry containing the following word whose frequency should
|
||||
# override the unigram frequency when following the word this bigram is
|
||||
# for.
|
||||
#
|
||||
dictionary=main:en,locale=en,description=Sample wordlist,date=1351495318,version=1
|
||||
word=sample,f=200
|
||||
bigram=wordlist,f=243
|
||||
word=wordlist,f=180
|
||||
word=shortcut,f=176
|
||||
shortcut=target,f=10
|
||||
word=witelisted,f=10,not_a_word=true
|
||||
shortcut=whitelisted,f=whitelist
|
||||
word=profanity,f=0
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AppWorkaroundsHelper {
|
||||
private AppWorkaroundsHelper() {
|
||||
// This helper class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static boolean evaluateIsBrokenByRecorrection(final PackageInfo info) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.dictionarypack;
|
||||
|
||||
/**
|
||||
* A class to group constants for dictionary pack usage.
|
||||
*
|
||||
* This class only defines constants. It should not make any references to outside code as far as
|
||||
* possible, as it's used to separate cleanly the keyboard code from the dictionary pack code; this
|
||||
* is needed in particular to cleanly compile regression tests.
|
||||
*/
|
||||
public class DictionaryPackConstants {
|
||||
/**
|
||||
* The root domain for the dictionary pack, upon which authorities and actions will append
|
||||
* their own distinctive strings.
|
||||
*/
|
||||
private static final String DICTIONARY_DOMAIN = "com.android.inputmethod.dictionarypack.aosp";
|
||||
|
||||
/**
|
||||
* Authority for the ContentProvider protocol.
|
||||
*/
|
||||
// TODO: find some way to factorize this string with the one in the resources
|
||||
public static final String AUTHORITY = DICTIONARY_DOMAIN;
|
||||
|
||||
/**
|
||||
* The action of the intent for publishing that new dictionary data is available.
|
||||
*/
|
||||
// TODO: make this different across different packages. A suggested course of action is
|
||||
// to use the package name inside this string.
|
||||
// NOTE: The appended string should be uppercase like all other actions, but it's not for
|
||||
// historical reasons.
|
||||
public static final String NEW_DICTIONARY_INTENT_ACTION = DICTIONARY_DOMAIN + ".newdict";
|
||||
|
||||
/**
|
||||
* The action of the intent sent by the dictionary pack to ask for a client to make
|
||||
* itself known. This is used when the settings activity is brought up for a client the
|
||||
* dictionary pack does not know about.
|
||||
*/
|
||||
public static final String UNKNOWN_DICTIONARY_PROVIDER_CLIENT = DICTIONARY_DOMAIN
|
||||
+ ".UNKNOWN_CLIENT";
|
||||
|
||||
// In the above intents, the name of the string extra that contains the name of the client
|
||||
// we want information about.
|
||||
public static final String DICTIONARY_PROVIDER_CLIENT_EXTRA = "client";
|
||||
|
||||
/**
|
||||
* The action of the intent to tell the dictionary provider to update now.
|
||||
*/
|
||||
public static final String UPDATE_NOW_INTENT_ACTION = DICTIONARY_DOMAIN
|
||||
+ ".UPDATE_NOW";
|
||||
|
||||
/**
|
||||
* The intent action to inform the dictionary provider to initialize the db
|
||||
* and update now.
|
||||
*/
|
||||
public static final String INIT_AND_UPDATE_NOW_INTENT_ACTION = DICTIONARY_DOMAIN
|
||||
+ ".INIT_AND_UPDATE_NOW";
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.dictionarypack;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Helper to get the metadata URI from its base URI.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class MetadataUriGetter {
|
||||
public static String getUri(final Context context, final String baseUri) {
|
||||
return baseUri;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.latin;
|
||||
|
||||
/**
|
||||
* Factory for instantiating DictionaryFacilitator objects.
|
||||
*/
|
||||
public class DictionaryFacilitatorProvider {
|
||||
public static DictionaryFacilitator getDictionaryFacilitator(boolean isNeededForSpellChecking) {
|
||||
return new DictionaryFacilitatorImpl();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.latin.about;
|
||||
|
||||
import android.app.Fragment;
|
||||
|
||||
/**
|
||||
* Dummy class of AboutPreferences. Never use this.
|
||||
*/
|
||||
public final class AboutPreferences extends Fragment {
|
||||
private AboutPreferences() {
|
||||
// Prevents this from being instantiated
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.latin.accounts;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Handles changes to account used to sign in to the keyboard.
|
||||
* e.g. account switching/sign-in/sign-out from the keyboard
|
||||
* user toggling the sync preference.
|
||||
*/
|
||||
public class AccountStateChangedListener {
|
||||
|
||||
/**
|
||||
* Called when the current account being used in keyboard is signed out.
|
||||
*
|
||||
* @param oldAccount the account that was signed out of.
|
||||
*/
|
||||
public static void onAccountSignedOut(@NonNull String oldAccount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user signs-in to the keyboard.
|
||||
* This may be called when the user switches accounts to sign in with a different account.
|
||||
*
|
||||
* @param oldAccount the previous account that was being used for sign-in.
|
||||
* May be null for a fresh sign-in.
|
||||
* @param newAccount the account being used for sign-in.
|
||||
*/
|
||||
public static void onAccountSignedIn(@Nullable String oldAccount, @NonNull String newAccount) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user toggles the sync preference.
|
||||
*
|
||||
* @param account the account being used for sync.
|
||||
* @param syncEnabled indicates whether sync has been enabled or not.
|
||||
*/
|
||||
public static void onSyncPreferenceChanged(@Nullable String account, boolean syncEnabled) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces an immediate sync to happen.
|
||||
* This should only be used for debugging purposes.
|
||||
*
|
||||
* @param account the account to use for sync.
|
||||
*/
|
||||
public static void forceSync(@Nullable String account) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces an immediate deletion of user's data.
|
||||
* This should only be used for debugging purposes.
|
||||
*
|
||||
* @param account the account to use for sync.
|
||||
*/
|
||||
public static void forceDelete(@Nullable String account) {
|
||||
}
|
||||
}
|
|
@ -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.latin.accounts;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Utility class for retrieving accounts that may be used for login.
|
||||
*/
|
||||
public class LoginAccountUtils {
|
||||
/**
|
||||
* This defines the type of account this class deals with.
|
||||
* This account type is used when listing the accounts available on the device for login.
|
||||
*/
|
||||
public static final String ACCOUNT_TYPE = "";
|
||||
|
||||
private LoginAccountUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the accounts available for login.
|
||||
*
|
||||
* @return an array of accounts. Empty (never null) if no accounts are available for login.
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("unused")
|
||||
public static String[] getAccountsForLogin(final Context context) {
|
||||
return new String[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.latin.define;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
public final class DebugFlags {
|
||||
public static final boolean DEBUG_ENABLED = false;
|
||||
|
||||
private DebugFlags() {
|
||||
// This class is not publicly instantiable.
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void init(final SharedPreferences prefs) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2015 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.latin.define;
|
||||
|
||||
/**
|
||||
* Decoder specific constants for LatinIme.
|
||||
*/
|
||||
public class DecoderSpecificConstants {
|
||||
|
||||
// Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
|
||||
public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
|
||||
|
||||
// (MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1)-gram is supported in Java side. Needs to modify
|
||||
// MAX_PREV_WORD_COUNT_FOR_N_GRAM in native/jni/src/defines.h for suggestions.
|
||||
public static final int MAX_PREV_WORD_COUNT_FOR_N_GRAM = 3;
|
||||
|
||||
public static final String DECODER_DICT_SUFFIX = "";
|
||||
|
||||
public static final boolean SHOULD_VERIFY_MAGIC_NUMBER = true;
|
||||
public static final boolean SHOULD_VERIFY_CHECKSUM = true;
|
||||
public static final boolean SHOULD_USE_DICT_VERSION = true;
|
||||
public static final boolean SHOULD_AUTO_CORRECT_USING_NON_WHITE_LISTED_SUGGESTION = false;
|
||||
public static final boolean SHOULD_REMOVE_PREVIOUSLY_REJECTED_SUGGESTION = true;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.latin.define;
|
||||
|
||||
public final class JniLibName {
|
||||
private JniLibName() {
|
||||
// This class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static final String JNI_LIB_NAME = "jni_latinime";
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2012 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.latin.define;
|
||||
|
||||
public final class ProductionFlags {
|
||||
private ProductionFlags() {
|
||||
// This class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static final boolean IS_HARDWARE_KEYBOARD_SUPPORTED = false;
|
||||
|
||||
/**
|
||||
* Include all suggestions from all dictionaries in
|
||||
* {@link com.android.inputmethod.latin.SuggestedWords#mRawSuggestions}.
|
||||
*/
|
||||
public static final boolean INCLUDE_RAW_SUGGESTIONS = false;
|
||||
|
||||
/**
|
||||
* When false, the metrics logging is not yet ready to be enabled.
|
||||
*/
|
||||
public static final boolean IS_METRICS_LOGGING_SUPPORTED = false;
|
||||
|
||||
/**
|
||||
* When {@code false}, the split keyboard is not yet ready to be enabled.
|
||||
*/
|
||||
public static final boolean IS_SPLIT_KEYBOARD_SUPPORTED = true;
|
||||
|
||||
/**
|
||||
* When {@code false}, account sign-in in keyboard is not yet ready to be enabled.
|
||||
*/
|
||||
public static final boolean ENABLE_ACCOUNT_SIGN_IN = false;
|
||||
|
||||
/**
|
||||
* When {@code true}, user history dictionary sync feature is ready to be enabled.
|
||||
*/
|
||||
public static final boolean ENABLE_USER_HISTORY_DICTIONARY_SYNC =
|
||||
ENABLE_ACCOUNT_SIGN_IN && false;
|
||||
|
||||
/**
|
||||
* When {@code true}, the IME maintains per account {@link UserHistoryDictionary}.
|
||||
*/
|
||||
public static final boolean ENABLE_PER_ACCOUNT_USER_HISTORY_DICTIONARY =
|
||||
ENABLE_ACCOUNT_SIGN_IN && false;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.latin.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Utility class for managing additional features settings.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class AdditionalFeaturesSettingUtils {
|
||||
public static final int ADDITIONAL_FEATURES_SETTINGS_SIZE = 0;
|
||||
|
||||
private AdditionalFeaturesSettingUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
public static void addAdditionalFeaturesPreferences(
|
||||
final Context context, final PreferenceFragment settingsFragment) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
public static void readAdditionalFeaturesPreferencesIntoArray(final Context context,
|
||||
final SharedPreferences prefs, final int[] additionalFeaturesPreferences) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static RichInputMethodSubtype createRichInputMethodSubtype(
|
||||
@Nonnull final RichInputMethodManager imm,
|
||||
@Nonnull final InputMethodSubtype subtype,
|
||||
final Context context) {
|
||||
return new RichInputMethodSubtype(subtype);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.latin.touchinputconsumer;
|
||||
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
|
||||
import com.android.inputmethod.keyboard.Keyboard;
|
||||
import com.android.inputmethod.latin.DictionaryFacilitator;
|
||||
import com.android.inputmethod.latin.SuggestedWords;
|
||||
import com.android.inputmethod.latin.common.InputPointers;
|
||||
import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Stub for GestureConsumer.
|
||||
* <br>
|
||||
* The methods of this class should only be called from a single thread, e.g.,
|
||||
* the UI Thread.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class GestureConsumer {
|
||||
public static final GestureConsumer NULL_GESTURE_CONSUMER =
|
||||
new GestureConsumer();
|
||||
|
||||
public static GestureConsumer newInstance(
|
||||
final EditorInfo editorInfo, final PrivateCommandPerformer commandPerformer,
|
||||
final Locale locale, final Keyboard keyboard) {
|
||||
return GestureConsumer.NULL_GESTURE_CONSUMER;
|
||||
}
|
||||
|
||||
private GestureConsumer() {
|
||||
}
|
||||
|
||||
public boolean willConsume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onInit(final Locale locale, final Keyboard keyboard) {
|
||||
}
|
||||
|
||||
public void onGestureStarted(final Locale locale, final Keyboard keyboard) {
|
||||
}
|
||||
|
||||
public void onGestureCanceled() {
|
||||
}
|
||||
|
||||
public void onGestureCompleted(final InputPointers inputPointers) {
|
||||
}
|
||||
|
||||
public void onImeSuggestionsProcessed(final SuggestedWords suggestedWords,
|
||||
final int composingStart, final int composingLength,
|
||||
final DictionaryFacilitator dictionaryFacilitator) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) 2015 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.latin.utils;
|
||||
|
||||
import com.android.inputmethod.latin.AssetFileAddress;
|
||||
import com.android.inputmethod.latin.makedict.DictionaryHeader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class DictionaryHeaderUtils {
|
||||
|
||||
public static int getContentVersion(AssetFileAddress fileAddress) {
|
||||
final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(
|
||||
new File(fileAddress.mFilename), fileAddress.mOffset, fileAddress.mLength);
|
||||
return Integer.parseInt(header.mVersionString);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.latin.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class FeedbackUtils {
|
||||
public static boolean isHelpAndFeedbackFormSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void showHelpAndFeedbackForm(Context context) {
|
||||
}
|
||||
|
||||
public static int getAboutKeyboardTitleResId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Intent getAboutKeyboardIntent(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.latin.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public final class FileTransforms {
|
||||
public static OutputStream getCryptedStream(OutputStream out) {
|
||||
// Crypt the stream.
|
||||
return out;
|
||||
}
|
||||
|
||||
public static InputStream getDecryptedStream(InputStream in) {
|
||||
// Decrypt the stream.
|
||||
return in;
|
||||
}
|
||||
|
||||
public static InputStream getUncompressedStream(InputStream in) throws IOException {
|
||||
return new GZIPInputStream(in);
|
||||
}
|
||||
}
|
|
@ -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.latin.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
|
||||
public class ManagedProfileUtils {
|
||||
private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils();
|
||||
private static ManagedProfileUtils sTestInstance;
|
||||
|
||||
private ManagedProfileUtils() {
|
||||
// This utility class is not publicly instantiable.
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public static void setTestInstance(final ManagedProfileUtils testInstance) {
|
||||
sTestInstance = testInstance;
|
||||
}
|
||||
|
||||
public static ManagedProfileUtils getInstance() {
|
||||
return sTestInstance == null ? INSTANCE : sTestInstance;
|
||||
}
|
||||
|
||||
public boolean hasWorkProfile(final Context context) {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.latin.utils;
|
||||
|
||||
import com.android.inputmethod.latin.R;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Helper class to get the metadata URI and the additional ID.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class MetadataFileUriGetter {
|
||||
private MetadataFileUriGetter() {
|
||||
// This helper class is not instantiable.
|
||||
}
|
||||
|
||||
public static String getMetadataUri(final Context context) {
|
||||
return context.getString(R.string.dictionary_pack_metadata_uri);
|
||||
}
|
||||
|
||||
public static String getMetadataAdditionalId(final Context context) {
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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.latin.utils;
|
||||
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.DictionaryFacilitator;
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.SuggestedWords;
|
||||
import com.android.inputmethod.latin.settings.SettingsValues;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class StatsUtils {
|
||||
|
||||
private StatsUtils() {
|
||||
// Intentional empty constructor.
|
||||
}
|
||||
|
||||
public static void onCreate(final SettingsValues settingsValues,
|
||||
RichInputMethodManager richImm) {
|
||||
}
|
||||
|
||||
public static void onPickSuggestionManually(final SuggestedWords suggestedWords,
|
||||
final SuggestedWords.SuggestedWordInfo suggestionInfo,
|
||||
final DictionaryFacilitator dictionaryFacilitator) {
|
||||
}
|
||||
|
||||
public static void onBackspaceWordDelete(int wordLength) {
|
||||
}
|
||||
|
||||
public static void onBackspacePressed(int lengthToDelete) {
|
||||
}
|
||||
|
||||
public static void onBackspaceSelectedText(int selectedTextLength) {
|
||||
}
|
||||
|
||||
public static void onDeleteMultiCharInput(int multiCharLength) {
|
||||
}
|
||||
|
||||
public static void onRevertAutoCorrect() {
|
||||
}
|
||||
|
||||
public static void onRevertDoubleSpacePeriod() {
|
||||
}
|
||||
|
||||
public static void onRevertSwapPunctuation() {
|
||||
}
|
||||
|
||||
public static void onFinishInputView() {
|
||||
}
|
||||
|
||||
public static void onCreateInputView() {
|
||||
}
|
||||
|
||||
public static void onStartInputView(int inputType, int displayOrientation, boolean restarting) {
|
||||
}
|
||||
|
||||
public static void onAutoCorrection(final String typedWord, final String autoCorrectionWord,
|
||||
final boolean isBatchInput, final DictionaryFacilitator dictionaryFacilitator,
|
||||
final String prevWordsContext) {
|
||||
}
|
||||
|
||||
public static void onWordCommitUserTyped(final String commitWord, final boolean isBatchMode) {
|
||||
}
|
||||
|
||||
public static void onWordCommitAutoCorrect(final String commitWord, final boolean isBatchMode) {
|
||||
}
|
||||
|
||||
public static void onWordCommitSuggestionPickedManually(
|
||||
final String commitWord, final boolean isBatchMode) {
|
||||
}
|
||||
|
||||
public static void onDoubleSpacePeriod() {
|
||||
}
|
||||
|
||||
public static void onLoadSettings(SettingsValues settingsValues) {
|
||||
}
|
||||
|
||||
public static void onInvalidWordIdentification(final String invalidWord) {
|
||||
}
|
||||
|
||||
public static void onSubtypeChanged(final InputMethodSubtype oldSubtype,
|
||||
final InputMethodSubtype newSubtype) {
|
||||
}
|
||||
|
||||
public static void onSettingsActivity(final String entryPoint) {
|
||||
}
|
||||
|
||||
public static void onInputConnectionLaggy(final int operation, final long duration) {
|
||||
}
|
||||
|
||||
public static void onDecoderLaggy(final int operation, final long duration) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.latin.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.inputmethod.latin.DictionaryFacilitator;
|
||||
import com.android.inputmethod.latin.settings.SettingsValues;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class StatsUtilsManager {
|
||||
|
||||
private static final StatsUtilsManager sInstance = new StatsUtilsManager();
|
||||
private static StatsUtilsManager sTestInstance = null;
|
||||
|
||||
/**
|
||||
* @return the singleton instance of {@link StatsUtilsManager}.
|
||||
*/
|
||||
public static StatsUtilsManager getInstance() {
|
||||
return sTestInstance != null ? sTestInstance : sInstance;
|
||||
}
|
||||
|
||||
public static void setTestInstance(final StatsUtilsManager testInstance) {
|
||||
sTestInstance = testInstance;
|
||||
}
|
||||
|
||||
public void onCreate(final Context context, final DictionaryFacilitator dictionaryFacilitator) {
|
||||
}
|
||||
|
||||
public void onLoadSettings(final Context context, final SettingsValues settingsValues) {
|
||||
}
|
||||
|
||||
public void onStartInputView() {
|
||||
}
|
||||
|
||||
public void onFinishInputView() {
|
||||
}
|
||||
|
||||
public void onDestroy(final Context context) {
|
||||
}
|
||||
}
|
46
android/packages/inputmethods/LatinIME/java/Android.mk
Normal file
|
@ -0,0 +1,46 @@
|
|||
# Copyright (C) 2011 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src ../java-overridable/src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := LatinIME
|
||||
|
||||
LOCAL_CERTIFICATE := shared
|
||||
|
||||
LOCAL_JNI_SHARED_LIBRARIES := libjni_latinime
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
android-common inputmethod-common jsr305 latinime-common
|
||||
|
||||
LOCAL_STATIC_ANDROID_LIBRARIES := \
|
||||
android-support-v4
|
||||
|
||||
LOCAL_USE_AAPT2 := true
|
||||
|
||||
# Do not compress dictionary files to mmap dict data runtime
|
||||
LOCAL_AAPT_FLAGS := -0 .dict
|
||||
|
||||
# Include all the resources regardless of system supported locales
|
||||
LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
|
||||
include $(BUILD_PACKAGE)
|
193
android/packages/inputmethods/LatinIME/java/AndroidManifest.xml
Normal file
|
@ -0,0 +1,193 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2012 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
coreApp="true"
|
||||
package="com.android.inputmethod.latin">
|
||||
|
||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.READ_PROFILE" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
|
||||
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
|
||||
|
||||
<!-- A signature-protected permission to ask AOSP Keyboard to close the software keyboard.
|
||||
To use this, add the following line into calling application's AndroidManifest.xml
|
||||
<pre>
|
||||
{@code
|
||||
<uses-permission android:name="com.android.inputmethod.latin.HIDE_SOFT_INPUT"/>
|
||||
}
|
||||
</pre>
|
||||
then call {@link android.content.Context#sendBroadcast(Intent)} as follows:
|
||||
<pre>
|
||||
{@code
|
||||
sendBroadcast(new Intent("com.android.inputmethod.latin.HIDE_SOFT_INPUT")
|
||||
.setPackage("com.android.inputmethod.latin"));
|
||||
}
|
||||
</pre> -->
|
||||
<permission android:name="com.android.inputmethod.latin.HIDE_SOFT_INPUT"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<application android:label="@string/english_ime_name"
|
||||
android:icon="@drawable/ic_launcher_keyboard"
|
||||
android:supportsRtl="true"
|
||||
android:allowBackup="true"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
android:directBootAware="true">
|
||||
|
||||
<!-- Services -->
|
||||
<service android:name="LatinIME"
|
||||
android:label="@string/english_ime_name"
|
||||
android:permission="android.permission.BIND_INPUT_METHOD">
|
||||
<intent-filter>
|
||||
<action android:name="android.view.InputMethod" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.view.im" android:resource="@xml/method" />
|
||||
</service>
|
||||
|
||||
<service android:name=".spellcheck.AndroidSpellCheckerService"
|
||||
android:label="@string/spell_checker_service_name"
|
||||
android:permission="android.permission.BIND_TEXT_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.textservice.SpellCheckerService" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.view.textservice.scs"
|
||||
android:resource="@xml/spellchecker" />
|
||||
</service>
|
||||
|
||||
<service android:name="com.android.inputmethod.dictionarypack.DictionaryService"
|
||||
android:label="@string/dictionary_service_name">
|
||||
</service>
|
||||
|
||||
<!-- Activities -->
|
||||
<activity android:name=".setup.SetupActivity"
|
||||
android:theme="@style/platformActivityTheme"
|
||||
android:label="@string/english_ime_name"
|
||||
android:icon="@drawable/ic_launcher_keyboard"
|
||||
android:launchMode="singleTask"
|
||||
android:noHistory="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".permissions.PermissionsActivity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:exported="false"
|
||||
android:taskAffinity="" >
|
||||
</activity>
|
||||
|
||||
<activity android:name=".setup.SetupWizardActivity"
|
||||
android:theme="@style/platformActivityTheme"
|
||||
android:label="@string/english_ime_name"
|
||||
android:clearTaskOnLaunch="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".settings.SettingsActivity"
|
||||
android:theme="@style/platformSettingsTheme"
|
||||
android:label="@string/english_ime_settings">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".spellcheck.SpellCheckerSettingsActivity"
|
||||
android:theme="@style/platformSettingsTheme"
|
||||
android:label="@string/android_spell_checker_settings">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.android.inputmethod.dictionarypack.DictionarySettingsActivity"
|
||||
android:theme="@style/platformSettingsTheme"
|
||||
android:label="@string/dictionary_settings_title"
|
||||
android:uiOptions="splitActionBarWhenNarrow">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.android.inputmethod.dictionarypack.DownloadOverMeteredDialog"
|
||||
android:theme="@style/platformActivityTheme"
|
||||
android:label="@string/dictionary_install_over_metered_network_prompt">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Unexported activity used for tests. -->
|
||||
<activity android:name=".settings.TestFragmentActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<!-- Broadcast receivers -->
|
||||
<receiver android:name="SystemBroadcastReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.USER_INITIALIZE" />
|
||||
<action android:name="android.intent.action.LOCALE_CHANGED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="DictionaryPackInstallBroadcastReceiver" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.inputmethod.dictionarypack.aosp.UNKNOWN_CLIENT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="com.android.inputmethod.dictionarypack.EventHandler">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
<action android:name="android.intent.action.DATE_CHANGED" />
|
||||
<action android:name="com.android.inputmethod.dictionarypack.aosp.UPDATE_NOW" />
|
||||
<action android:name="com.android.inputmethod.dictionarypack.aosp.INIT_AND_UPDATE_NOW" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Broadcast receiver for AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION. -->
|
||||
<receiver android:name=".accounts.AccountsChangedReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Content providers -->
|
||||
<provider android:name="com.android.inputmethod.dictionarypack.DictionaryProvider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false"
|
||||
android:authorities="@string/authority"
|
||||
android:multiprocess="false"
|
||||
android:label="@string/dictionary_provider_name">
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
192
android/packages/inputmethods/LatinIME/java/NOTICE
Normal file
|
@ -0,0 +1,192 @@
|
|||
|
||||
Copyright (c) 2008, 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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Includes Dictionaries © Lexiteria LLC. Used by permission.
|
28
android/packages/inputmethods/LatinIME/java/proguard.flags
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Keep classes and methods that have the @UsedForTesting annotation
|
||||
-keep @com.android.inputmethod.annotations.UsedForTesting class *
|
||||
-keepclassmembers class * {
|
||||
@com.android.inputmethod.annotations.UsedForTesting *;
|
||||
}
|
||||
|
||||
# Keep classes and methods that have the @ExternallyReferenced annotation
|
||||
-keep @com.android.inputmethod.annotations.ExternallyReferenced class *
|
||||
-keepclassmembers class * {
|
||||
@com.android.inputmethod.annotations.ExternallyReferenced *;
|
||||
}
|
||||
|
||||
# Keep native methods
|
||||
-keepclassmembers class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# Keep classes that are used as a parameter type of methods that are also marked as keep
|
||||
# to preserve changing those methods' signature.
|
||||
-keep class com.android.inputmethod.latin.AssetFileAddress
|
||||
-keep class com.android.inputmethod.latin.Dictionary
|
||||
-keep class com.android.inputmethod.latin.NgramContext
|
||||
-keep class com.android.inputmethod.latin.makedict.ProbabilityInfo
|
||||
-keep class com.android.inputmethod.latin.utils.LanguageModelParam
|
||||
|
||||
# TODO: remove once used in code.
|
||||
-keep class com.android.inputmethod.keyboard.KeyboardLayout { *; }
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="altCodeKeyWhileTypingAnimAlpha"
|
||||
android:valueType="intType"
|
||||
android:duration="1000"
|
||||
android:valueFrom="128"
|
||||
android:valueTo="255" />
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="altCodeKeyWhileTypingAnimAlpha"
|
||||
android:valueType="intType"
|
||||
android:duration="3000"
|
||||
android:valueFrom="255"
|
||||
android:valueTo="128" />
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
</set>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="53"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="0.94" />
|
||||
</set>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
</set>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="scaleX"
|
||||
android:duration="17"
|
||||
android:valueFrom="1.00"
|
||||
android:valueTo="1.00" />
|
||||
<objectAnimator
|
||||
android:propertyName="scaleY"
|
||||
android:duration="17"
|
||||
android:valueFrom="0.98"
|
||||
android:valueTo="1.00" />
|
||||
</set>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 2012, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="languageOnSpacebarAnimAlpha"
|
||||
android:valueType="intType"
|
||||
android:startOffset="1200"
|
||||
android:duration="200"
|
||||
android:valueFrom="255"
|
||||
android:valueTo="@integer/config_language_on_spacebar_final_alpha" />
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_focused="true"
|
||||
android:color="@color/setup_text_action" />
|
||||
<item
|
||||
android:state_pressed="true"
|
||||
android:color="@color/setup_text_action" />
|
||||
<item
|
||||
android:color="@color/setup_step_background" />
|
||||
</selector>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
**
|
||||
** Copyright 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_focused="true"
|
||||
android:color="@color/setup_step_background" />
|
||||
<item
|
||||
android:state_pressed="true"
|
||||
android:color="@color/setup_step_background" />
|
||||
<item
|
||||
android:color="@color/setup_text_action" />
|
||||
</selector>
|
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 244 B |
After Width: | Height: | Size: 587 B |
After Width: | Height: | Size: 639 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 272 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 244 B |
After Width: | Height: | Size: 553 B |