aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/event
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/event')
-rw-r--r--java/src/com/android/inputmethod/event/Combiner.java29
-rw-r--r--java/src/com/android/inputmethod/event/DeadKeyCombiner.java61
-rw-r--r--java/src/com/android/inputmethod/event/Event.java93
-rw-r--r--java/src/com/android/inputmethod/event/EventDecoder.java24
-rw-r--r--java/src/com/android/inputmethod/event/EventDecoderSpec.java26
-rw-r--r--java/src/com/android/inputmethod/event/EventInterpreter.java133
-rw-r--r--java/src/com/android/inputmethod/event/HardwareEventDecoder.java26
-rw-r--r--java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java74
-rw-r--r--java/src/com/android/inputmethod/event/SoftwareEventDecoder.java29
-rw-r--r--java/src/com/android/inputmethod/event/SoftwareKeyboardEventDecoder.java27
10 files changed, 522 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/event/Combiner.java b/java/src/com/android/inputmethod/event/Combiner.java
new file mode 100644
index 000000000..ab6b70c04
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/Combiner.java
@@ -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.event;
+
+/**
+ * A generic interface for combiners.
+ */
+public interface Combiner {
+ /**
+ * Combine an event with the existing state and return the new event.
+ * @param event the event to combine with the existing state.
+ * @return the resulting event.
+ */
+ Event combine(Event event);
+}
diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
new file mode 100644
index 000000000..52987d571
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java
@@ -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.event;
+
+import android.text.TextUtils;
+import android.view.KeyCharacterMap;
+
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * A combiner that handles dead keys.
+ */
+public class DeadKeyCombiner implements Combiner {
+ final StringBuilder mDeadSequence = new StringBuilder();
+
+ @Override
+ public Event combine(final Event event) {
+ if (null == event) return null; // Just in case some combiner is broken
+ if (TextUtils.isEmpty(mDeadSequence)) {
+ if (event.isDead()) {
+ mDeadSequence.appendCodePoint(event.mCodePoint);
+ }
+ return event;
+ } else {
+ // TODO: Allow combining for several dead chars rather than only the first one.
+ // The framework doesn't know how to do this now.
+ final int deadCodePoint = mDeadSequence.codePointAt(0);
+ mDeadSequence.setLength(0);
+ final int resultingCodePoint =
+ KeyCharacterMap.getDeadChar(deadCodePoint, event.mCodePoint);
+ if (0 == resultingCodePoint) {
+ // We can't combine both characters. We need to commit the dead key as a committable
+ // character, and the next char too unless it's a space (because as a special case,
+ // dead key + space should result in only the dead key being committed - that's
+ // how dead keys work).
+ // If the event is a space, we should commit the dead char alone, but if it's
+ // not, we need to commit both.
+ return Event.createCommittableEvent(deadCodePoint,
+ Constants.CODE_SPACE == event.mCodePoint ? null : event /* next */);
+ } else {
+ // We could combine the characters.
+ return Event.createCommittableEvent(resultingCodePoint, null /* next */);
+ }
+ }
+ }
+
+}
diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java
new file mode 100644
index 000000000..1f3320eb7
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/Event.java
@@ -0,0 +1,93 @@
+/*
+ * 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.event;
+
+/**
+ * Class representing a generic input event as handled by Latin IME.
+ *
+ * This contains information about the origin of the event, but it is generalized and should
+ * represent a software keypress, hardware keypress, or d-pad move alike.
+ * Very importantly, this does not necessarily result in inputting one character, or even anything
+ * at all - it may be a dead key, it may be a partial input, it may be a special key on the
+ * keyboard, it may be a cancellation of a keypress (e.g. in a soft keyboard the finger of the
+ * user has slid out of the key), etc. It may also be a batch input from a gesture or handwriting
+ * for example.
+ * The combiner should figure out what to do with this.
+ */
+public class Event {
+ // Should the types below be represented by separate classes instead? It would be cleaner
+ // but probably a bit too much
+ // An event we don't handle in Latin IME, for example pressing Ctrl on a hardware keyboard.
+ final public static int EVENT_NOT_HANDLED = 0;
+ // A character that is already final, for example pressing an alphabetic character on a
+ // hardware qwerty keyboard.
+ final public static int EVENT_COMMITTABLE = 1;
+ // A dead key, which means a character that should combine with what is coming next. Examples
+ // include the "^" character on an azerty keyboard which combines with "e" to make "ê", or
+ // AltGr+' on a dvorak international keyboard which combines with "e" to make "é". This is
+ // true regardless of the language or combining mode, and should be seen as a property of the
+ // key - a dead key followed by another key with which it can combine should be regarded as if
+ // the keyboard actually had such a key.
+ final public static int EVENT_DEAD = 2;
+ // A toggle event is triggered by a key that affects the previous character. An example would
+ // be a numeric key on a 10-key keyboard, which would toggle between 1 - a - b - c with
+ // repeated presses.
+ final public static int EVENT_TOGGLE = 3;
+ // A mode event instructs the combiner to change modes. The canonical example would be the
+ // hankaku/zenkaku key on a Japanese keyboard, or even the caps lock key on a qwerty keyboard
+ // if handled at the combiner level.
+ final public static int EVENT_MODE_KEY = 4;
+
+ final private static int NOT_A_CODE_POINT = 0;
+
+ final private int mType; // The type of event - one of the constants above
+ // The code point associated with the event, if relevant. This is a unicode code point, and
+ // has nothing to do with other representations of the key. It is only relevant if this event
+ // is the right type: COMMITTABLE or DEAD or TOGGLE, but for a mode key like hankaku/zenkaku or
+ // ctrl, there is no code point associated so this should be NOT_A_CODE_POINT to avoid
+ // unintentional use of its value when it's not relevant.
+ final public int mCodePoint;
+ // The next event, if any. Null if there is no next event yet.
+ final public Event mNextEvent;
+
+ // This method is private - to create a new event, use one of the create* utility methods.
+ private Event(final int type, final int codePoint, final Event next) {
+ mType = type;
+ mCodePoint = codePoint;
+ mNextEvent = next;
+ }
+
+ public static Event createDeadEvent(final int codePoint, final Event next) {
+ return new Event(EVENT_DEAD, codePoint, next);
+ }
+
+ public static Event createCommittableEvent(final int codePoint, final Event next) {
+ return new Event(EVENT_COMMITTABLE, codePoint, next);
+ }
+
+ public static Event createNotHandledEvent() {
+ return new Event(EVENT_NOT_HANDLED, NOT_A_CODE_POINT, null);
+ }
+
+ public boolean isCommittable() {
+ return EVENT_COMMITTABLE == mType;
+ }
+
+ public boolean isDead() {
+ return EVENT_DEAD == mType;
+ }
+}
diff --git a/java/src/com/android/inputmethod/event/EventDecoder.java b/java/src/com/android/inputmethod/event/EventDecoder.java
new file mode 100644
index 000000000..7ff0166a3
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/EventDecoder.java
@@ -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.event;
+
+/**
+ * A generic interface for event decoders.
+ */
+public interface EventDecoder {
+
+}
diff --git a/java/src/com/android/inputmethod/event/EventDecoderSpec.java b/java/src/com/android/inputmethod/event/EventDecoderSpec.java
new file mode 100644
index 000000000..303b4b4c9
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/EventDecoderSpec.java
@@ -0,0 +1,26 @@
+/*
+ * 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.event;
+
+/**
+ * Class describing a decoder chain. This will depend on the language and the input medium (soft
+ * or hard keyboard for example).
+ */
+public class EventDecoderSpec {
+ public EventDecoderSpec() {
+ }
+}
diff --git a/java/src/com/android/inputmethod/event/EventInterpreter.java b/java/src/com/android/inputmethod/event/EventInterpreter.java
new file mode 100644
index 000000000..6efe899bb
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/EventInterpreter.java
@@ -0,0 +1,133 @@
+/*
+ * 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.event;
+
+import android.util.SparseArray;
+import android.view.KeyEvent;
+
+import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.LatinIME;
+
+import java.util.ArrayList;
+
+/**
+ * This class implements the logic between receiving events and generating code points.
+ *
+ * Event sources are multiple. It may be a hardware keyboard, a D-PAD, a software keyboard,
+ * or any exotic input source.
+ * This class will orchestrate the decoding chain that starts with an event and ends up with
+ * a stream of code points + decoding state.
+ */
+public class EventInterpreter {
+ // TODO: Implement an object pool for events, as we'll create a lot of them
+ // TODO: Create a combiner
+ // TODO: Create an object type to represent input material + visual feedback + decoding state
+ // TODO: Create an interface to call back to Latin IME through the above object
+
+ final EventDecoderSpec mDecoderSpec;
+ final SparseArray<HardwareEventDecoder> mHardwareEventDecoders;
+ final SoftwareEventDecoder mSoftwareEventDecoder;
+ final LatinIME mLatinIme;
+ final ArrayList<Combiner> mCombiners;
+
+ /**
+ * Create a default interpreter.
+ *
+ * This creates a default interpreter that does nothing. A default interpreter should normally
+ * only be used for fallback purposes, when we really don't know what we want to do with input.
+ *
+ * @param latinIme a reference to the ime.
+ */
+ public EventInterpreter(final LatinIME latinIme) {
+ this(null, latinIme);
+ }
+
+ /**
+ * Create an event interpreter according to a specification.
+ *
+ * The specification contains information about what to do with events. Typically, it will
+ * contain information about the type of keyboards - for example, if hardware keyboard(s) is/are
+ * attached, their type will be included here so that the decoder knows what to do with each
+ * keypress (a 10-key keyboard is not handled like a qwerty-ish keyboard).
+ * It also contains information for combining characters. For example, if the input language
+ * is Japanese, the specification will typically request kana conversion.
+ * Also note that the specification can be null. This means that we need to create a default
+ * interpreter that does no specific combining, and assumes the most common cases.
+ *
+ * @param specification the specification for event interpretation. null for default.
+ * @param latinIme a reference to the ime.
+ */
+ public EventInterpreter(final EventDecoderSpec specification, final LatinIME latinIme) {
+ mDecoderSpec = null != specification ? specification : new EventDecoderSpec();
+ // For both, we expect to have only one decoder in almost all cases, hence the default
+ // capacity of 1.
+ mHardwareEventDecoders = new SparseArray<HardwareEventDecoder>(1);
+ mSoftwareEventDecoder = new SoftwareKeyboardEventDecoder();
+ mCombiners = CollectionUtils.newArrayList();
+ mCombiners.add(new DeadKeyCombiner());
+ mLatinIme = latinIme;
+ }
+
+ // Helper method to decode a hardware key event into a generic event, and execute any
+ // necessary action.
+ public boolean onHardwareKeyEvent(final KeyEvent hardwareKeyEvent) {
+ final Event decodedEvent = getHardwareKeyEventDecoder(hardwareKeyEvent.getDeviceId())
+ .decodeHardwareKey(hardwareKeyEvent);
+ return onEvent(decodedEvent);
+ }
+
+ public boolean onSoftwareEvent() {
+ final Event decodedEvent = getSoftwareEventDecoder().decodeSoftwareEvent();
+ return onEvent(decodedEvent);
+ }
+
+ private HardwareEventDecoder getHardwareKeyEventDecoder(final int deviceId) {
+ final HardwareEventDecoder decoder = mHardwareEventDecoders.get(deviceId);
+ if (null != decoder) return decoder;
+ // TODO: create the decoder according to the specification
+ final HardwareEventDecoder newDecoder = new HardwareKeyboardEventDecoder(deviceId);
+ mHardwareEventDecoders.put(deviceId, newDecoder);
+ return newDecoder;
+ }
+
+ private SoftwareEventDecoder getSoftwareEventDecoder() {
+ // Within the context of Latin IME, since we never present several software interfaces
+ // at the time, we should never need multiple software event decoders at a time.
+ return mSoftwareEventDecoder;
+ }
+
+ private boolean onEvent(final Event event) {
+ Event currentlyProcessingEvent = event;
+ boolean processed = false;
+ for (int i = 0; i < mCombiners.size(); ++i) {
+ currentlyProcessingEvent = mCombiners.get(i).combine(event);
+ }
+ while (null != currentlyProcessingEvent) {
+ if (currentlyProcessingEvent.isCommittable()) {
+ mLatinIme.onCodeInput(currentlyProcessingEvent.mCodePoint,
+ Constants.EXTERNAL_KEYBOARD_COORDINATE,
+ Constants.EXTERNAL_KEYBOARD_COORDINATE);
+ processed = true;
+ } else if (event.isDead()) {
+ processed = true;
+ }
+ currentlyProcessingEvent = currentlyProcessingEvent.mNextEvent;
+ }
+ return processed;
+ }
+}
diff --git a/java/src/com/android/inputmethod/event/HardwareEventDecoder.java b/java/src/com/android/inputmethod/event/HardwareEventDecoder.java
new file mode 100644
index 000000000..6a6bd7bc5
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/HardwareEventDecoder.java
@@ -0,0 +1,26 @@
+/*
+ * 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.event;
+
+import android.view.KeyEvent;
+
+/**
+ * An event decoder for hardware events.
+ */
+public interface HardwareEventDecoder extends EventDecoder {
+ public Event decodeHardwareKey(final KeyEvent keyEvent);
+}
diff --git a/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java b/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
new file mode 100644
index 000000000..720d07433
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
@@ -0,0 +1,74 @@
+/*
+ * 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.event;
+
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * A hardware event decoder for a hardware qwerty-ish keyboard.
+ *
+ * The events are always hardware keypresses, but they can be key down or key up events, they
+ * can be dead keys, they can be meta keys like shift or ctrl... This does not deal with
+ * 10-key like keyboards; a different decoder is used for this.
+ */
+public class HardwareKeyboardEventDecoder implements HardwareEventDecoder {
+ final int mDeviceId;
+
+ public HardwareKeyboardEventDecoder(final int deviceId) {
+ mDeviceId = deviceId;
+ // TODO: get the layout for this hardware keyboard
+ }
+
+ @Override
+ public Event decodeHardwareKey(final KeyEvent keyEvent) {
+ // KeyEvent#getUnicodeChar() does not exactly returns a unicode char, but rather a value
+ // that includes both the unicode char in the lower 21 bits and flags in the upper bits,
+ // hence the name "codePointAndFlags". {@see KeyEvent#getUnicodeChar()} for more info.
+ final int codePointAndFlags = keyEvent.getUnicodeChar();
+ // The keyCode is the abstraction used by the KeyEvent to represent different keys that
+ // do not necessarily map to a unicode character. This represents a physical key, like
+ // the key for 'A' or Space, but also Backspace or Ctrl or Caps Lock.
+ final int keyCode = keyEvent.getKeyCode();
+ if (KeyEvent.KEYCODE_DEL == keyCode) {
+ return Event.createCommittableEvent(Constants.CODE_DELETE, null /* next */);
+ }
+ if (keyEvent.isPrintingKey() || KeyEvent.KEYCODE_SPACE == keyCode
+ || KeyEvent.KEYCODE_ENTER == keyCode) {
+ if (0 != (codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT)) {
+ // A dead key.
+ return Event.createDeadEvent(
+ codePointAndFlags & KeyCharacterMap.COMBINING_ACCENT_MASK, null /* next */);
+ }
+ if (KeyEvent.KEYCODE_ENTER == keyCode) {
+ // The Enter key. If the Shift key is not being pressed, this should send a
+ // CODE_ENTER to trigger the action if any, or a carriage return otherwise. If the
+ // Shift key is being pressed, this should send a CODE_SHIFT_ENTER and let
+ // Latin IME decide what to do with it.
+ return Event.createCommittableEvent(keyEvent.isShiftPressed()
+ ? Constants.CODE_SHIFT_ENTER : Constants.CODE_ENTER,
+ null /* next */);
+ }
+ // If not Enter, then we have a committable character. This should be committed
+ // right away, taking into account the current state.
+ return Event.createCommittableEvent(codePointAndFlags, null /* next */);
+ }
+ return Event.createNotHandledEvent();
+ }
+}
diff --git a/java/src/com/android/inputmethod/event/SoftwareEventDecoder.java b/java/src/com/android/inputmethod/event/SoftwareEventDecoder.java
new file mode 100644
index 000000000..d81ee0b37
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/SoftwareEventDecoder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.event;
+
+/**
+ * An event decoder for events out of a software keyboard.
+ *
+ * This defines the interface for an event decoder that supports events out of a software keyboard.
+ * This differs significantly from hardware keyboard event decoders in several respects. First,
+ * a software keyboard does not have a scancode/layout system; the keypresses that insert
+ * characters output unicode characters directly.
+ */
+public interface SoftwareEventDecoder extends EventDecoder {
+ public Event decodeSoftwareEvent();
+}
diff --git a/java/src/com/android/inputmethod/event/SoftwareKeyboardEventDecoder.java b/java/src/com/android/inputmethod/event/SoftwareKeyboardEventDecoder.java
new file mode 100644
index 000000000..de91567c7
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/SoftwareKeyboardEventDecoder.java
@@ -0,0 +1,27 @@
+/*
+ * 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.event;
+
+/**
+ * A decoder for events from software keyboard, like the ones displayed by Latin IME.
+ */
+public class SoftwareKeyboardEventDecoder implements SoftwareEventDecoder {
+ @Override
+ public Event decodeSoftwareEvent() {
+ return null;
+ }
+}