/* * Copyright (C) 2017 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 androidx.emoji.util; import android.app.Instrumentation; import android.text.Selection; import android.text.Spannable; import android.text.method.QwertyKeyListener; import android.text.method.TextKeyListener; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.widget.TextView; import java.util.concurrent.CountDownLatch; /** * Utility class for KeyEvents */ public class KeyboardUtil { private static final int ALT = KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON; private static final int CTRL = KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON; private static final int SHIFT = KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON; private static final int FN = KeyEvent.META_FUNCTION_ON; public static KeyEvent zero() { return keyEvent(KeyEvent.KEYCODE_0); } public static KeyEvent del() { return keyEvent(KeyEvent.KEYCODE_DEL); } public static KeyEvent altDel() { return keyEvent(KeyEvent.KEYCODE_DEL, ALT); } public static KeyEvent ctrlDel() { return keyEvent(KeyEvent.KEYCODE_DEL, CTRL); } public static KeyEvent shiftDel() { return keyEvent(KeyEvent.KEYCODE_DEL, SHIFT); } public static KeyEvent fnDel() { return keyEvent(KeyEvent.KEYCODE_DEL, FN); } public static KeyEvent forwardDel() { return keyEvent(KeyEvent.KEYCODE_FORWARD_DEL); } public static KeyEvent keyEvent(int keycode, int metaState) { final long currentTime = System.currentTimeMillis(); return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0, metaState); } public static KeyEvent keyEvent(int keycode) { final long currentTime = System.currentTimeMillis(); return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0); } public static void setComposingTextInBatch(final Instrumentation instrumentation, final InputConnection inputConnection, final CharSequence text) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); instrumentation.runOnMainSync(new Runnable() { @Override public void run() { inputConnection.beginBatchEdit(); inputConnection.setComposingText(text, 1); inputConnection.endBatchEdit(); latch.countDown(); } }); latch.await(); instrumentation.waitForIdleSync(); } public static void deleteSurroundingText(final Instrumentation instrumentation, final InputConnection inputConnection, final int before, final int after) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); instrumentation.runOnMainSync(new Runnable() { @Override public void run() { inputConnection.beginBatchEdit(); inputConnection.deleteSurroundingText(before, after); inputConnection.endBatchEdit(); latch.countDown(); } }); latch.await(); instrumentation.waitForIdleSync(); } public static void setSelection(Instrumentation instrumentation, final Spannable spannable, final int start) throws InterruptedException { setSelection(instrumentation, spannable, start, start); } public static void setSelection(Instrumentation instrumentation, final Spannable spannable, final int start, final int end) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); instrumentation.runOnMainSync(new Runnable() { @Override public void run() { Selection.setSelection(spannable, start, end); latch.countDown(); } }); latch.await(); instrumentation.waitForIdleSync(); } public static InputConnection initTextViewForSimulatedIme(Instrumentation instrumentation, final TextView textView) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); instrumentation.runOnMainSync(new Runnable() { @Override public void run() { textView.setKeyListener( QwertyKeyListener.getInstance(false, TextKeyListener.Capitalize.NONE)); textView.setText("", TextView.BufferType.EDITABLE); latch.countDown(); } }); latch.await(); instrumentation.waitForIdleSync(); return textView.onCreateInputConnection(new EditorInfo()); } }