Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package androidx.emoji.util;
     17 
     18 import android.app.Instrumentation;
     19 import android.text.Selection;
     20 import android.text.Spannable;
     21 import android.text.method.QwertyKeyListener;
     22 import android.text.method.TextKeyListener;
     23 import android.view.KeyEvent;
     24 import android.view.inputmethod.EditorInfo;
     25 import android.view.inputmethod.InputConnection;
     26 import android.widget.TextView;
     27 
     28 import java.util.concurrent.CountDownLatch;
     29 
     30 /**
     31  * Utility class for KeyEvents
     32  */
     33 public class KeyboardUtil {
     34     private static final int ALT = KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON;
     35     private static final int CTRL = KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON;
     36     private static final int SHIFT = KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON;
     37     private static final int FN = KeyEvent.META_FUNCTION_ON;
     38 
     39     public static KeyEvent zero() {
     40         return keyEvent(KeyEvent.KEYCODE_0);
     41     }
     42 
     43     public static KeyEvent del() {
     44         return keyEvent(KeyEvent.KEYCODE_DEL);
     45     }
     46 
     47     public static KeyEvent altDel() {
     48         return keyEvent(KeyEvent.KEYCODE_DEL, ALT);
     49     }
     50 
     51     public static KeyEvent ctrlDel() {
     52         return keyEvent(KeyEvent.KEYCODE_DEL, CTRL);
     53     }
     54 
     55     public static KeyEvent shiftDel() {
     56         return keyEvent(KeyEvent.KEYCODE_DEL, SHIFT);
     57     }
     58 
     59     public static KeyEvent fnDel() {
     60         return keyEvent(KeyEvent.KEYCODE_DEL, FN);
     61     }
     62 
     63     public static KeyEvent forwardDel() {
     64         return keyEvent(KeyEvent.KEYCODE_FORWARD_DEL);
     65     }
     66 
     67     public static KeyEvent keyEvent(int keycode, int metaState) {
     68         final long currentTime = System.currentTimeMillis();
     69         return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0, metaState);
     70     }
     71 
     72     public static KeyEvent keyEvent(int keycode) {
     73         final long currentTime = System.currentTimeMillis();
     74         return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0);
     75     }
     76 
     77     public static void setComposingTextInBatch(final Instrumentation instrumentation,
     78             final InputConnection inputConnection, final CharSequence text)
     79             throws InterruptedException {
     80         final CountDownLatch latch = new CountDownLatch(1);
     81         instrumentation.runOnMainSync(new Runnable() {
     82             @Override
     83             public void run() {
     84                 inputConnection.beginBatchEdit();
     85                 inputConnection.setComposingText(text, 1);
     86                 inputConnection.endBatchEdit();
     87                 latch.countDown();
     88             }
     89         });
     90 
     91         latch.await();
     92         instrumentation.waitForIdleSync();
     93     }
     94 
     95     public static void deleteSurroundingText(final Instrumentation instrumentation,
     96             final InputConnection inputConnection, final int before, final int after)
     97             throws InterruptedException {
     98         final CountDownLatch latch = new CountDownLatch(1);
     99         instrumentation.runOnMainSync(new Runnable() {
    100             @Override
    101             public void run() {
    102                 inputConnection.beginBatchEdit();
    103                 inputConnection.deleteSurroundingText(before, after);
    104                 inputConnection.endBatchEdit();
    105                 latch.countDown();
    106             }
    107         });
    108         latch.await();
    109         instrumentation.waitForIdleSync();
    110     }
    111 
    112     public static void setSelection(Instrumentation instrumentation, final Spannable spannable,
    113             final int start) throws InterruptedException {
    114         setSelection(instrumentation, spannable, start, start);
    115     }
    116 
    117     public static void setSelection(Instrumentation instrumentation, final Spannable spannable,
    118             final int start, final int end) throws InterruptedException {
    119         final CountDownLatch latch = new CountDownLatch(1);
    120         instrumentation.runOnMainSync(new Runnable() {
    121             @Override
    122             public void run() {
    123                 Selection.setSelection(spannable, start, end);
    124                 latch.countDown();
    125             }
    126         });
    127         latch.await();
    128         instrumentation.waitForIdleSync();
    129     }
    130 
    131     public static InputConnection initTextViewForSimulatedIme(Instrumentation instrumentation,
    132             final TextView textView) throws InterruptedException {
    133         final CountDownLatch latch = new CountDownLatch(1);
    134         instrumentation.runOnMainSync(new Runnable() {
    135             @Override
    136             public void run() {
    137                 textView.setKeyListener(
    138                         QwertyKeyListener.getInstance(false, TextKeyListener.Capitalize.NONE));
    139                 textView.setText("", TextView.BufferType.EDITABLE);
    140                 latch.countDown();
    141             }
    142         });
    143         latch.await();
    144         instrumentation.waitForIdleSync();
    145         return textView.onCreateInputConnection(new EditorInfo());
    146     }
    147 }
    148