Create the path for specifying combining rules in the subtype
Also add the skeleton of the combining rules for Myanmar reordering as a pilot. Bug: 13945569 Change-Id: Iabeb6838f45f1efff482143595ce5b48543e0c43
This commit is contained in:
parent
c41d261b7e
commit
be99616afa
10 changed files with 138 additions and 3 deletions
|
@ -503,7 +503,7 @@
|
|||
android:subtypeId="0xea266ea4"
|
||||
android:imeSubtypeLocale="my_MM"
|
||||
android:imeSubtypeMode="keyboard"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable,CombiningRules=MyanmarReordering"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher_dark"
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.android.inputmethod.latin.Constants;
|
|||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class implements the logic chain between receiving events and generating code points.
|
||||
|
@ -43,6 +44,13 @@ public class CombinerChain {
|
|||
private SpannableStringBuilder mStateFeedback;
|
||||
private final ArrayList<Combiner> mCombiners;
|
||||
|
||||
private static final HashMap<String, Class> IMPLEMENTED_COMBINERS
|
||||
= new HashMap<String, Class>();
|
||||
static {
|
||||
IMPLEMENTED_COMBINERS.put("MyanmarReordering", MyanmarReordering.class);
|
||||
}
|
||||
private static final String COMBINER_SPEC_SEPARATOR = ";";
|
||||
|
||||
/**
|
||||
* Create an combiner chain.
|
||||
*
|
||||
|
@ -56,6 +64,9 @@ public class CombinerChain {
|
|||
mCombiners = CollectionUtils.newArrayList();
|
||||
// The dead key combiner is always active, and always first
|
||||
mCombiners.add(new DeadKeyCombiner());
|
||||
for (final Combiner combiner : combinerList) {
|
||||
mCombiners.add(combiner);
|
||||
}
|
||||
mCombinedText = new StringBuilder();
|
||||
mStateFeedback = new SpannableStringBuilder();
|
||||
}
|
||||
|
@ -114,4 +125,29 @@ public class CombinerChain {
|
|||
final SpannableStringBuilder s = new SpannableStringBuilder(mCombinedText);
|
||||
return s.append(mStateFeedback);
|
||||
}
|
||||
|
||||
public static Combiner[] createCombiners(final String spec) {
|
||||
if (TextUtils.isEmpty(spec)) {
|
||||
return new Combiner[0];
|
||||
}
|
||||
final String[] combinerDescriptors = spec.split(COMBINER_SPEC_SEPARATOR);
|
||||
final Combiner[] combiners = new Combiner[combinerDescriptors.length];
|
||||
int i = 0;
|
||||
for (final String combinerDescriptor : combinerDescriptors) {
|
||||
final Class combinerClass = IMPLEMENTED_COMBINERS.get(combinerDescriptor);
|
||||
if (null == combinerClass) {
|
||||
throw new RuntimeException("Unknown combiner descriptor: " + combinerDescriptor);
|
||||
}
|
||||
try {
|
||||
combiners[i++] = (Combiner)combinerClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("Unable to instantiate combiner: " + combinerDescriptor,
|
||||
e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Unable to instantiate combiner: " + combinerDescriptor,
|
||||
e);
|
||||
}
|
||||
}
|
||||
return combiners;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A combiner that reorders input for Myanmar.
|
||||
*/
|
||||
public class MyanmarReordering implements Combiner {
|
||||
@Override
|
||||
public Event processEvent(ArrayList<Event> previousEvents, Event event) {
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCombiningStateFeedback() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
}
|
||||
}
|
|
@ -115,6 +115,11 @@ public final class Constants {
|
|||
*/
|
||||
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.
|
||||
}
|
||||
|
|
|
@ -733,6 +733,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
|
||||
// is not guaranteed. It may even be called at the same time on a different thread.
|
||||
mSubtypeSwitcher.onSubtypeChanged(subtype);
|
||||
mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype));
|
||||
loadKeyboard();
|
||||
}
|
||||
|
||||
|
@ -808,7 +809,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|
||||
// The app calling setText() has the effect of clearing the composing
|
||||
// span, so we should reset our state unconditionally, even if restarting is true.
|
||||
mInputLogic.startInput(restarting, editorInfo);
|
||||
// We also tell the input logic about the combining rules for the current subtype, so
|
||||
// it can adjust its combiners if needed.
|
||||
mInputLogic.startInput(restarting, editorInfo,
|
||||
mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
|
||||
|
||||
// Note: the following does a round-trip IPC on the main thread: be careful
|
||||
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
|
||||
|
|
|
@ -326,4 +326,8 @@ public final class SubtypeSwitcher {
|
|||
+ DUMMY_EMOJI_SUBTYPE);
|
||||
return DUMMY_EMOJI_SUBTYPE;
|
||||
}
|
||||
|
||||
public String getCombiningRulesExtraValueOfCurrentSubtype() {
|
||||
return SubtypeLocaleUtils.getCombiningRulesExtraValue(getCurrentSubtype());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ public final class WordComposer {
|
|||
public static final int CAPS_MODE_AUTO_SHIFT_LOCKED = 0x7;
|
||||
|
||||
private CombinerChain mCombinerChain;
|
||||
private String mCombiningSpec; // Memory so that we don't uselessly recreate the combiner chain
|
||||
|
||||
// The list of events that served to compose this string.
|
||||
private final ArrayList<Event> mEvents;
|
||||
|
@ -90,6 +91,21 @@ public final class WordComposer {
|
|||
refreshTypedWordCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart input with a new combining spec.
|
||||
* @param combiningSpec The spec string for combining. This is found in the extra value.
|
||||
*/
|
||||
public void restart(final String combiningSpec) {
|
||||
final String nonNullCombiningSpec = null == combiningSpec ? "" : combiningSpec;
|
||||
if (nonNullCombiningSpec.equals(mCombiningSpec)) {
|
||||
mCombinerChain.reset();
|
||||
} else {
|
||||
mCombinerChain = new CombinerChain(CombinerChain.createCombiners(nonNullCombiningSpec));
|
||||
mCombiningSpec = nonNullCombiningSpec;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the keys registered so far.
|
||||
*/
|
||||
|
|
|
@ -97,6 +97,11 @@ public final class InputLogic {
|
|||
private boolean mIsAutoCorrectionIndicatorOn;
|
||||
private long mDoubleSpacePeriodCountdownStart;
|
||||
|
||||
/**
|
||||
* Create a new instance of the input logic.
|
||||
* @param latinIME the instance of the parent LatinIME. We should remove this when we can.
|
||||
* @param suggestionStripViewAccessor an object to access the suggestion strip view.
|
||||
*/
|
||||
public InputLogic(final LatinIME latinIME,
|
||||
final SuggestionStripViewAccessor suggestionStripViewAccessor) {
|
||||
mLatinIME = latinIME;
|
||||
|
@ -117,9 +122,12 @@ public final class InputLogic {
|
|||
*
|
||||
* @param restarting whether input is starting in the same field as before. Unused for now.
|
||||
* @param editorInfo the editorInfo associated with the editor.
|
||||
* @param combiningSpec the combining spec string for this subtype
|
||||
*/
|
||||
public void startInput(final boolean restarting, final EditorInfo editorInfo) {
|
||||
public void startInput(final boolean restarting, final EditorInfo editorInfo,
|
||||
final String combiningSpec) {
|
||||
mEnteredText = null;
|
||||
mWordComposer.restart(combiningSpec);
|
||||
resetComposingState(true /* alsoResetLastComposedWord */);
|
||||
mDeleteCount = 0;
|
||||
mSpaceState = SpaceState.NONE;
|
||||
|
@ -137,6 +145,14 @@ public final class InputLogic {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when the subtype changes.
|
||||
* @param combiningSpec the spec string for the combining rules
|
||||
*/
|
||||
public void onSubtypeChanged(final String combiningSpec) {
|
||||
mWordComposer.restart(combiningSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the input logic after input is finished.
|
||||
*/
|
||||
|
|
|
@ -324,4 +324,8 @@ public final class SubtypeLocaleUtils {
|
|||
public static boolean isRtlLanguage(final InputMethodSubtype subtype) {
|
||||
return isRtlLanguage(getSubtypeLocale(subtype));
|
||||
}
|
||||
|
||||
public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) {
|
||||
return subtype.getExtraValueOf(Constants.Subtype.ExtraValue.COMBINING_RULES);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Compatibility class that stands in for the combiner chain in LatinIME.
|
||||
*
|
||||
* This is not used by dicttool, it's just needed by the dependency chain.
|
||||
*/
|
||||
// TODO: there should not be a dependency to this in dicttool, so there
|
||||
// should be a sensible way to separate them cleanly.
|
||||
public class CombinerChain {
|
||||
private StringBuilder mComposingWord = new StringBuilder();
|
||||
public CombinerChain(final Combiner... combinerList) {}
|
||||
|
@ -35,4 +42,9 @@ public class CombinerChain {
|
|||
public void reset() {
|
||||
mComposingWord.setLength(0);
|
||||
}
|
||||
|
||||
public static Combiner[] createCombiners(final String spec) {
|
||||
// Dicttool never uses a combiner at all, so we just return a zero-sized array.
|
||||
return new Combiner[0];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue