From cff28c5d5db3e0c3e97149519a3f705150aeb224 Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Thu, 6 Dec 2012 20:35:59 +0900
Subject: [PATCH] Add skeleton classes for hardware event flow (B1)

Bug: 5037589
Change-Id: Id8eea0e2bd00dd339a1efb4b0542e4c091a84195
---
 .../com/android/inputmethod/event/Event.java  | 36 ++++++++
 .../inputmethod/event/EventDecoder.java       | 24 ++++++
 .../inputmethod/event/EventDecoderSpec.java   | 26 ++++++
 .../inputmethod/event/EventInterpreter.java   | 82 +++++++++++++++++++
 .../event/HardwareEventDecoder.java           | 26 ++++++
 .../event/HardwareKeyboardEventDecoder.java   | 36 ++++++++
 .../event/SoftwareEventDecoder.java           | 24 ++++++
 .../android/inputmethod/latin/LatinIME.java   | 25 ++++++
 8 files changed, 279 insertions(+)
 create mode 100644 java/src/com/android/inputmethod/event/Event.java
 create mode 100644 java/src/com/android/inputmethod/event/EventDecoder.java
 create mode 100644 java/src/com/android/inputmethod/event/EventDecoderSpec.java
 create mode 100644 java/src/com/android/inputmethod/event/EventInterpreter.java
 create mode 100644 java/src/com/android/inputmethod/event/HardwareEventDecoder.java
 create mode 100644 java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
 create mode 100644 java/src/com/android/inputmethod/event/SoftwareEventDecoder.java

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 0000000000..c96a3362d9
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/Event.java
@@ -0,0 +1,36 @@
+/*
+ * 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 {
+    static Event obtainEvent() {
+        // TODO: create an event pool instead
+        return new Event();
+    }
+}
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 0000000000..7ff0166a36
--- /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 0000000000..303b4b4c9e
--- /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 0000000000..443c269a27
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/EventInterpreter.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+/**
+ * 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
+
+    // TODO: replace this with an associative container to bind device id -> decoder
+    HardwareEventDecoder mHardwareEventDecoder;
+    SoftwareEventDecoder mSoftwareEventDecoder;
+
+    public EventInterpreter() {
+        this(null);
+    }
+
+    public EventInterpreter(final EventDecoderSpec specification) {
+        // TODO: create the decoding chain from a specification. The decoders should be
+        // created lazily
+        mHardwareEventDecoder = new HardwareKeyboardEventDecoder(0);
+    }
+
+    // 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) {
+        // TODO: look up the decoder by device id. It should be created lazily
+        return mHardwareEventDecoder;
+    }
+
+    private SoftwareEventDecoder getSoftwareEventDecoder() {
+        return mSoftwareEventDecoder;
+    }
+
+    private boolean onEvent(final Event event) {
+        // TODO: Classify the event - input or non-input (see design doc)
+        // TODO: IF action event
+        //          Send decoded action back to LatinIME
+        //       ELSE
+        //          Send input event to the combiner
+        //          Get back new input material + visual feedback + combiner state
+        //          Route the event to Latin IME
+        //       ENDIF
+        return false;
+    }
+}
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 0000000000..6a6bd7bc5f
--- /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 0000000000..9aa6a273e7
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/HardwareKeyboardEventDecoder.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * A hardware event decoder for a hardware qwerty-ish keyboard.
+ */
+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(KeyEvent keyEvent) {
+        return Event.obtainEvent();
+    }
+}
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 0000000000..0b80d5c0e2
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/SoftwareEventDecoder.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;
+
+/**
+ * An event decoder for software events.
+ */
+public interface SoftwareEventDecoder extends EventDecoder {
+    public Event decodeSoftwareEvent();
+}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 19076d2e7d..f0705a890c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -64,6 +64,7 @@ import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.compat.CompatUtils;
 import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
 import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.event.EventInterpreter;
 import com.android.inputmethod.keyboard.KeyDetector;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardActionListener;
@@ -142,6 +143,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
     @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
     private final SubtypeSwitcher mSubtypeSwitcher;
     private final SubtypeState mSubtypeState = new SubtypeState();
+    // At start, create a default event interpreter that does nothing by passing it no decoder spec.
+    // The event interpreter should never be null.
+    private EventInterpreter mEventInterpreter = new EventInterpreter();
 
     private boolean mIsMainDictionaryAvailable;
     private UserBinaryDictionary mUserDictionary;
@@ -2376,6 +2380,27 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         }
     }
 
+    // Hooks for hardware keyboard
+    @Override
+    public boolean onKeyDown(final int keyCode, final KeyEvent event) {
+        // onHardwareKeyEvent, like onKeyDown returns true if it handled the event, false if
+        // it doesn't know what to do with it and leave it to the application. For example,
+        // hardware key events for adjusting the screen's brightness are passed as is.
+        if (mEventInterpreter.onHardwareKeyEvent(event)) return true;
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKeyUp(final int keyCode, final KeyEvent event) {
+        if (mEventInterpreter.onHardwareKeyEvent(event)) return true;
+        return super.onKeyUp(keyCode, event);
+    }
+
+    // onKeyDown and onKeyUp are the main events we are interested in. There are two more events
+    // related to handling of hardware key events that we may want to implement in the future:
+    // boolean onKeyLongPress(final int keyCode, final KeyEvent event);
+    // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event);
+
     // receive ringer mode change and network state change.
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
-- 
GitLab