ImeAdapter.java revision a36e5920737c6adbddd3e43b760e5de8431db6e0
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)package org.chromium.content.browser.input;
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.os.Handler;
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.os.ResultReceiver;
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.view.KeyCharacterMap;
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.view.KeyEvent;
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.view.View;
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.view.inputmethod.EditorInfo;
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import com.google.common.annotations.VisibleForTesting;
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.CalledByNative;
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.JNINamespace;
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/**
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Adapts and plumbs android IME service onto the chrome text input API.
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * ImeAdapter provides an interface in both ways native <-> java:
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 1. InputConnectionAdapter notifies native code of text composition state and
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *    dispatch key events from java -> WebKit.
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 2. Native ImeAdapter notifies java side to clear composition text.
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * The basic flow is:
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 1. When InputConnectionAdapter gets called with composition or result text:
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *    If we receive a composition text or a result text, then we just need to
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *    dispatch a synthetic key event with special keycode 229, and then dispatch
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *    the composition or result text.
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 2. Intercept dispatchKeyEvent() method for key events not handled by IME, we
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *   need to dispatch them to webkit and check webkit's reply. Then inject a
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *   new key event for further processing if webkit didn't handle it.
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Note that the native peer object does not take any strong reference onto the
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * instance of this java object, hence it is up to the client of this class (e.g.
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * the ViewEmbedder implementor) to hold a strong reference to it for the required
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * lifetime of the object.
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@JNINamespace("content")
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)public class ImeAdapter {
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    public interface ImeAdapterDelegate {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        /**
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         * @param isFinish whether the event is occurring because input is finished.
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         */
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        void onImeEvent(boolean isFinish);
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        void onSetFieldValue();
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        void onDismissInput();
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        View getAttachedView();
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ResultReceiver getNewShowKeyboardReceiver();
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private class DelayedDismissInput implements Runnable {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        private final int mNativeImeAdapter;
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        DelayedDismissInput(int nativeImeAdapter) {
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mNativeImeAdapter = nativeImeAdapter;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        @Override
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        public void run() {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            attach(mNativeImeAdapter, sTextInputTypeNone, AdapterInputConnection.INVALID_SELECTION,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    AdapterInputConnection.INVALID_SELECTION);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            dismissInput(true);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static final int COMPOSITION_KEY_CODE = 229;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Delay introduced to avoid hiding the keyboard if new show requests are received.
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The time required by the unfocus-focus events triggered by tab has been measured in soju:
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Mean: 18.633 ms, Standard deviation: 7.9837 ms.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The value here should be higher enough to cover these cases, but not too high to avoid
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // letting the user perceiving important delays.
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static final int INPUT_DISMISS_DELAY = 150;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // All the constants that are retrieved from the C++ code.
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // They get set through initializeWebInputEvents and initializeTextInputTypes calls.
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sEventTypeRawKeyDown;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sEventTypeKeyUp;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sEventTypeChar;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeNone;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeText;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeTextArea;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypePassword;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeSearch;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeUrl;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeEmail;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeTel;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeNumber;
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeWeek;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sTextInputTypeContentEditable;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sModifierShift;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sModifierAlt;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sModifierCtrl;
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sModifierCapsLockOn;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static int sModifierNumLockOn;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private int mNativeImeAdapterAndroid;
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private InputMethodManagerWrapper mInputMethodManagerWrapper;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private AdapterInputConnection mInputConnection;
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    private final ImeAdapterDelegate mViewEmbedder;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private final Handler mHandler;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private DelayedDismissInput mDismissInput = null;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private int mTextInputType;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private int mInitialSelectionStart;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private int mInitialSelectionEnd;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @VisibleForTesting
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean mIsShowWithoutHideOutstanding = false;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *                InputMethodManager.
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param embedder The view that is used for callbacks from ImeAdapter.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embedder) {
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        mInputMethodManagerWrapper = wrapper;
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mViewEmbedder = embedder;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mHandler = new Handler();
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public static class AdapterInputConnectionFactory {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                EditorInfo outAttrs) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return new AdapterInputConnection(view, imeAdapter, outAttrs);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @VisibleForTesting
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    public void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) {
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mInputMethodManagerWrapper = immw;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Should be only used by AdapterInputConnection.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return InputMethodManagerWrapper that should receive all the calls directed to
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     *         InputMethodManager.
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    InputMethodManagerWrapper getInputMethodManagerWrapper() {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mInputMethodManagerWrapper;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Set the current active InputConnection when a new InputConnection is constructed.
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param inputConnection The input connection that is currently used with IME.
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void setInputConnection(AdapterInputConnection inputConnection) {
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mInputConnection = inputConnection;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Should be only used by AdapterInputConnection.
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return The input type of currently focused element.
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int getTextInputType() {
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mTextInputType;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Should be only used by AdapterInputConnection.
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return The starting index of the initial text selection.
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int getInitialSelectionStart() {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mInitialSelectionStart;
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Should be only used by AdapterInputConnection.
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return The ending index of the initial text selection.
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int getInitialSelectionEnd() {
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mInitialSelectionEnd;
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public static int getTextInputTypeNone() {
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return sTextInputTypeNone;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static int getModifiers(int metaState) {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        int modifiers = 0;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((metaState & KeyEvent.META_SHIFT_ON) != 0) {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          modifiers |= sModifierShift;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((metaState & KeyEvent.META_ALT_ON) != 0) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          modifiers |= sModifierAlt;
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((metaState & KeyEvent.META_CTRL_ON) != 0) {
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          modifiers |= sModifierCtrl;
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          modifiers |= sModifierCapsLockOn;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) {
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          modifiers |= sModifierNumLockOn;
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return modifiers;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean isActive() {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mInputConnection != null && mInputConnection.isActive();
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private boolean isFor(int nativeImeAdapter, int textInputType) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mNativeImeAdapterAndroid == nativeImeAdapter &&
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               mTextInputType == textInputType;
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int selectionStart, int selectionEnd, boolean showIfNeeded) {
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mHandler.removeCallbacks(mDismissInput);
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // If current input type is none and showIfNeeded is false, IME should not be shown
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // and input type should remain as none.
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mTextInputType == sTextInputTypeNone && !showIfNeeded) {
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return;
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (!isFor(nativeImeAdapter, textInputType)) {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // Set a delayed task to perform unfocus. This avoids hiding the keyboard when tabbing
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // through text inputs or when JS rapidly changes focus to another text element.
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            if (textInputType == sTextInputTypeNone) {
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mDismissInput = new DelayedDismissInput(nativeImeAdapter);
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY);
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                return;
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int previousType = mTextInputType;
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            attach(nativeImeAdapter, textInputType, selectionStart, selectionEnd);
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mInputMethodManagerWrapper.restartInput(mViewEmbedder.getAttachedView());
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            if (showIfNeeded) {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                showKeyboard();
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else if (hasInputType() && showIfNeeded) {
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            showKeyboard();
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void attach(int nativeImeAdapter, int textInputType, int selectionStart,
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int selectionEnd) {
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid != 0) {
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeResetImeAdapter(mNativeImeAdapterAndroid);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mNativeImeAdapterAndroid = nativeImeAdapter;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mTextInputType = textInputType;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mInitialSelectionStart = selectionStart;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mInitialSelectionEnd = selectionEnd;
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        if (nativeImeAdapter != 0) {
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            nativeAttachImeAdapter(mNativeImeAdapterAndroid);
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        }
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Attaches the imeAdapter to its native counterpart. This is needed to start forwarding
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * keyboard events to WebKit.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param nativeImeAdapter The pointer to the native ImeAdapter object.
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public void attach(int nativeImeAdapter) {
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid != 0) {
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeResetImeAdapter(mNativeImeAdapterAndroid);
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mNativeImeAdapterAndroid = nativeImeAdapter;
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (nativeImeAdapter != 0) {
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeAttachImeAdapter(mNativeImeAdapterAndroid);
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Used to check whether the native counterpart of the ImeAdapter has been attached yet.
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether native ImeAdapter has been attached and its pointer is currently nonzero.
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean isNativeImeAdapterAttached() {
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mNativeImeAdapterAndroid != 0;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private void showKeyboard() {
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mIsShowWithoutHideOutstanding = true;
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mInputMethodManagerWrapper.showSoftInput(mViewEmbedder.getAttachedView(), 0,
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mViewEmbedder.getNewShowKeyboardReceiver());
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private void dismissInput(boolean unzoomIfNeeded) {
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        hideKeyboard(unzoomIfNeeded);
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mViewEmbedder.onDismissInput();
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private void hideKeyboard(boolean unzoomIfNeeded) {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mIsShowWithoutHideOutstanding  = false;
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        View view = mViewEmbedder.getAttachedView();
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mInputMethodManagerWrapper.isActive(view)) {
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mInputMethodManagerWrapper.hideSoftInputFromWindow(view.getWindowToken(), 0,
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    unzoomIfNeeded ? mViewEmbedder.getNewShowKeyboardReceiver() : null);
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private boolean hasInputType() {
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mTextInputType != sTextInputTypeNone;
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static boolean isTextInputType(int type) {
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return type != sTextInputTypeNone && !InputDialogContainer.isDialogInputType(type);
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean hasTextInputType() {
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return isTextInputType(mTextInputType);
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean dispatchKeyEvent(KeyEvent event) {
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return translateAndSendNativeEvents(event);
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private int shouldSendKeyEventWithKeyCode(String text) {
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (text.length() != 1) return COMPOSITION_KEY_CODE;
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        else return COMPOSITION_KEY_CODE;
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void sendKeyEventWithKeyCode(int keyCode, int flags) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        long eventTime = System.currentTimeMillis();
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                KeyEvent.ACTION_DOWN, keyCode, 0, 0,
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                flags));
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        translateAndSendNativeEvents(new KeyEvent(System.currentTimeMillis(), eventTime,
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                KeyEvent.ACTION_UP, keyCode, 0, 0,
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                flags));
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Calls from Java to C++
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @VisibleForTesting
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            boolean isCommit) {
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Committing an empty string finishes the current composition.
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        boolean isFinish = text.isEmpty();
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mViewEmbedder.onImeEvent(isFinish);
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        int keyCode = shouldSendKeyEventWithKeyCode(text);
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        long timeStampMs = System.currentTimeMillis();
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (keyCode != COMPOSITION_KEY_CODE) {
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            sendKeyEventWithKeyCode(keyCode,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    timeStampMs, keyCode, 0);
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            if (isCommit) {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                nativeCommitText(mNativeImeAdapterAndroid, text);
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            } else {
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                nativeSetComposingText(mNativeImeAdapterAndroid, text, newCursorPosition);
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    timeStampMs, keyCode, 0);
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    void finishComposingText() {
3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        nativeFinishComposingText(mNativeImeAdapterAndroid);
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean translateAndSendNativeEvents(KeyEvent event) {
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        int action = event.getAction();
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (action != KeyEvent.ACTION_DOWN &&
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            action != KeyEvent.ACTION_UP) {
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // action == KeyEvent.ACTION_MULTIPLE
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // TODO(bulach): confirm the actual behavior. Apparently:
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // composition key down (229) followed by a commit text with the
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // string from event.getUnicodeChars().
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // Otherwise, we'd need to send an event with a
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOWN,
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // and if that's the case, we'll need to review when to send the Char
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            // event.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return false;
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mViewEmbedder.onImeEvent(false);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getAction(),
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                getModifiers(event.getMetaState()), event.getEventTime(), event.getKeyCode(),
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                event.isSystem(), event.getUnicodeChar());
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean sendSyntheticKeyEvent(
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int eventType, long timestampMs, int keyCode, int unicodeChar) {
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeSendSyntheticKeyEvent(
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, unicodeChar);
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean deleteSurroundingText(int leftLength, int rightLength) {
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeDeleteSurroundingText(mNativeImeAdapterAndroid, leftLength, rightLength);
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @VisibleForTesting
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    protected boolean setEditableSelectionOffsets(int start, int end) {
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void batchStateChanged(boolean isBegin) {
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return;
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeImeBatchStateChanged(mNativeImeAdapterAndroid, isBegin);
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void commitText() {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        cancelComposition();
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid != 0) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            nativeCommitText(mNativeImeAdapterAndroid, "");
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart to set compositing region to given indices.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param start The start of the composition.
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param end The end of the composition.
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    boolean setComposingRegion(int start, int end) {
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart to unselect text.
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean unselect() {
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeUnselect(mNativeImeAdapterAndroid);
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart of ImeAdapter to select all the text.
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean selectAll() {
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeSelectAll(mNativeImeAdapterAndroid);
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart of ImeAdapter to cut the selected text.
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean cut() {
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeCut(mNativeImeAdapterAndroid);
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart of ImeAdapter to copy the selected text.
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean copy() {
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativeCopy(mNativeImeAdapterAndroid);
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Send a request to the native counterpart of ImeAdapter to paste the text from the clipboard.
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @return Whether the native counterpart of ImeAdapter received the call.
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    public boolean paste() {
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mNativeImeAdapterAndroid == 0) return false;
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        nativePaste(mNativeImeAdapterAndroid);
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return true;
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Calls from C++ to Java
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @CalledByNative
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static void initializeWebInputEvents(int eventTypeRawKeyDown, int eventTypeKeyUp,
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int eventTypeChar, int modifierShift, int modifierAlt, int modifierCtrl,
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int modifierCapsLockOn, int modifierNumLockOn) {
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sEventTypeRawKeyDown = eventTypeRawKeyDown;
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sEventTypeKeyUp = eventTypeKeyUp;
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sEventTypeChar = eventTypeChar;
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sModifierShift = modifierShift;
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sModifierAlt = modifierAlt;
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sModifierCtrl = modifierCtrl;
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sModifierCapsLockOn = modifierCapsLockOn;
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sModifierNumLockOn = modifierNumLockOn;
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @CalledByNative
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int textInputTypeNumber, int textInputTypeDate, int textInputTypeDateTime,
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int textInputTypeDateTimeLocal, int textInputTypeMonth, int textInputTypeTime,
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int textInputTypeWeek, int textInputTypeContentEditable) {
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeNone = textInputTypeNone;
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeText = textInputTypeText;
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeTextArea = textInputTypeTextArea;
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypePassword = textInputTypePassword;
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeSearch = textInputTypeSearch;
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeUrl = textInputTypeUrl;
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeEmail = textInputTypeEmail;
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeTel = textInputTypeTel;
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeNumber = textInputTypeNumber;
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeWeek = textInputTypeWeek;
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sTextInputTypeContentEditable = textInputTypeContentEditable;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @CalledByNative
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private void cancelComposition() {
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mInputConnection != null) {
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mInputConnection.restartInput();
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    @CalledByNative
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void detach() {
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mNativeImeAdapterAndroid = 0;
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mTextInputType = 0;
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native boolean nativeSendSyntheticKeyEvent(int nativeImeAdapterAndroid,
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int eventType, long timestampMs, int keyCode, int unicodeChar);
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native boolean nativeSendKeyEvent(int nativeImeAdapterAndroid, KeyEvent event,
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int action, int modifiers, long timestampMs, int keyCode, boolean isSystemKey,
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int unicodeChar);
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeSetComposingText(int nativeImeAdapterAndroid, String text,
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int newCursorPosition);
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeCommitText(int nativeImeAdapterAndroid, String text);
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    private native void nativeFinishComposingText(int nativeImeAdapterAndroid);
5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeAttachImeAdapter(int nativeImeAdapterAndroid);
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeSetEditableSelectionOffsets(int nativeImeAdapterAndroid,
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int start, int end);
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeSetComposingRegion(int nativeImeAdapterAndroid, int start, int end);
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeDeleteSurroundingText(int nativeImeAdapterAndroid,
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            int before, int after);
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeImeBatchStateChanged(int nativeImeAdapterAndroid, boolean isBegin);
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeUnselect(int nativeImeAdapterAndroid);
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeSelectAll(int nativeImeAdapterAndroid);
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeCut(int nativeImeAdapterAndroid);
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeCopy(int nativeImeAdapterAndroid);
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativePaste(int nativeImeAdapterAndroid);
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    private native void nativeResetImeAdapter(int nativeImeAdapterAndroid);
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
570