13487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su/*
23487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Copyright (C) 2008 The Android Open Source Project
33487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su *
43487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Licensed under the Apache License, Version 2.0 (the "License");
53487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * you may not use this file except in compliance with the License.
63487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * You may obtain a copy of the License at
73487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su *
83487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su *      http://www.apache.org/licenses/LICENSE-2.0
93487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su *
103487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Unless required by applicable law or agreed to in writing, software
113487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * distributed under the License is distributed on an "AS IS" BASIS,
123487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * See the License for the specific language governing permissions and
143487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * limitations under the License.
153487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su */
163487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
173487313ff582d8a7ae2bf58e7379c4577522dd61Scott Supackage android.text.method.cts;
183487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
193487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport com.android.cts.stub.R;
203487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
213487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
223487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.app.Activity;
233487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.app.Instrumentation;
243487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.os.SystemClock;
253487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.test.ActivityInstrumentationTestCase2;
263487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Editable;
273487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.InputType;
283487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Selection;
293487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.method.BaseKeyListener;
303487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.view.KeyCharacterMap;
313487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.view.KeyEvent;
323487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.view.View;
333487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.widget.TextView;
343487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.widget.TextView.BufferType;
353487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
363487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su/**
373487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Test the main functionalities of the BaseKeyListener.
383487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su */
393487313ff582d8a7ae2bf58e7379c4577522dd61Scott Supublic class BaseKeyListenerTest extends
403487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        ActivityInstrumentationTestCase2<KeyListenerStubActivity> {
413487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    private static final CharSequence TEST_STRING = "123456";
423487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    private Activity mActivity;
433487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    private Instrumentation mInstrumentation;
443487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    private TextView mTextView;
453487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
463487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    public BaseKeyListenerTest(){
473487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        super("com.android.cts.stub", KeyListenerStubActivity.class);
483487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    }
493487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
503487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    @Override
513487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    protected void setUp() throws Exception {
523487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        super.setUp();
533487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
543487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity = getActivity();
553487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation = getInstrumentation();
563487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mTextView = (TextView) mActivity.findViewById(R.id.keylistener_textview);
573487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    }
583487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
593487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    public void testBackspace() {
600edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        final Editable content = Editable.Factory.getInstance().newEditable(TEST_STRING);
610edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        setTextViewText(content);
620edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu
630edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Nothing to delete when the cursor is at the beginning.
643487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        final MockBaseKeyListener baseKeyListener = new MockBaseKeyListener();
653487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        KeyEvent delKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
663487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        Selection.setSelection(content, 0, 0);
673487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        baseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
683487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("123456", content.toString());
693487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
700edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Delete the first three letters using a selection.
710edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        setTextViewText(content);
723487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        Selection.setSelection(content, 0, 3);
733487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        baseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
743487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("456", content.toString());
753487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
760edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Delete the entire line wit ALT + DEL
770edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        setTextViewText(content);
780edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        KeyEvent altDelKeyEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL,
790edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                0, KeyEvent.META_ALT_ON);
800edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        Selection.setSelection(content, 0, 0);
810edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        baseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, altDelKeyEvent);
820edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        assertEquals("", content.toString());
830edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    }
843487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
850edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    private void setTextViewText(final CharSequence content) {
863487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity.runOnUiThread(new Runnable() {
873487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            public void run() {
880edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                mTextView.setText(content, BufferType.EDITABLE);
893487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            }
903487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        });
913487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
920edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    }
930edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu
940edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    public void testBackspace_withSendKeys() {
950edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        final MockBaseKeyListener baseKeyListener = new MockBaseKeyListener();
960edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        final String str = "123456";
970edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu
980edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Delete the first character '1'
990edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        prepareTextView(str, baseKeyListener, 1, 1);
1003487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        sendKeys(KeyEvent.KEYCODE_DEL);
1013487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("23456", mTextView.getText().toString());
1023487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1030edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Delete character '2' and '3'
1040edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        prepareTextView(str, baseKeyListener, 1, 3);
1053487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        sendKeys(KeyEvent.KEYCODE_DEL);
1063487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("1456", mTextView.getText().toString());
1073487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1080edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // Delete everything on the line the cursor is on.
1090edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        prepareTextView(str, baseKeyListener, 0, 0);
1100edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        sendAltDelete();
1113487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("", mTextView.getText().toString());
1123487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1133487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        // ALT+DEL deletes the selection only.
1140edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        prepareTextView(str, baseKeyListener, 2, 4);
1150edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        sendAltDelete();
1163487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("1256", mTextView.getText().toString());
1173487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1180edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        // DEL key does not take effect when TextView does not have BaseKeyListener.
1190edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        prepareTextView(str, null, 1, 1);
1200edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        sendKeys(KeyEvent.KEYCODE_DEL);
1210edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        assertEquals(str, mTextView.getText().toString());
1220edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    }
1230edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu
1240edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    private void prepareTextView(final CharSequence content, final BaseKeyListener keyListener,
1250edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu            final int selectionStart, final int selectionEnd) {
1263487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity.runOnUiThread(new Runnable() {
1273487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            public void run() {
1280edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                mTextView.setText(content, BufferType.EDITABLE);
1290edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                mTextView.setKeyListener(keyListener);
1303487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                mTextView.requestFocus();
1310edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                Selection.setSelection((Editable) mTextView.getText(), selectionStart,
1320edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu                        selectionEnd);
1333487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            }
1343487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        });
1353487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
1360edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    }
1370edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu
1380edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu    private void sendAltDelete() {
1390edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        mInstrumentation.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ALT_LEFT));
1403487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        sendKeys(KeyEvent.KEYCODE_DEL);
1410edb4aadc3edfa214260b4858c527a3d2dcb6cadBrian Muramatsu        mInstrumentation.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ALT_LEFT));
1423487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    }
1433487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1443487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    /**
1453487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su     * Check point:
1463487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su     * 1. Press 0 key, the content of TextView does not changed.
1473487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su     * 2. Set a selection and press DEL key, the selection is deleted.
1483487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su     * 3. ACTION_MULTIPLE KEYCODE_UNKNOWN by inserting the event's text into the content.
1493487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su     */
1503487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    public void testPressKey() {
1513487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        final CharSequence str = "123456";
1523487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        final MockBaseKeyListener baseKeyListener = new MockBaseKeyListener();
1533487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1543487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity.runOnUiThread(new Runnable() {
1553487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            public void run() {
1563487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                mTextView.setText(str, BufferType.EDITABLE);
1573487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                mTextView.setKeyListener(baseKeyListener);
1583487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                mTextView.requestFocus();
1593487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                Selection.setSelection((Editable) mTextView.getText(), 0, 0);
1603487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            }
1613487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        });
1623487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
1633487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("123456", mTextView.getText().toString());
1643487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        // press '0' key.
1653487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        sendKeys(KeyEvent.KEYCODE_0);
1663487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("123456", mTextView.getText().toString());
1673487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1683487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity.runOnUiThread(new Runnable() {
1693487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            public void run() {
1703487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                Selection.setSelection((Editable) mTextView.getText(), 1, 2);
1713487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            }
1723487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        });
1733487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
1743487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        // delete character '2'
1753487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        sendKeys(KeyEvent.KEYCODE_DEL);
1763487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        assertEquals("13456", mTextView.getText().toString());
1773487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1783487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mActivity.runOnUiThread(new Runnable() {
1793487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            public void run() {
1803487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                Selection.setSelection((Editable) mTextView.getText(), 2, 2);
1813487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            }
1823487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        });
1833487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
1843487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        // test ACTION_MULTIPLE KEYCODE_UNKNOWN key event.
1853487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), "abcd",
1863487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                KeyCharacterMap.BUILT_IN_KEYBOARD, 0);
1873487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.sendKeySync(event);
1883487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        mInstrumentation.waitForIdleSync();
1893487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        // the text of TextView is never changed, onKeyOther never works.
1903487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su//        assertEquals("13abcd456", mTextView.getText().toString());
1913487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    }
1923487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su
1933487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    private class MockBaseKeyListener extends BaseKeyListener {
1943487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        public int getInputType() {
1953487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su            return InputType.TYPE_CLASS_DATETIME
1963487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su                    | InputType.TYPE_DATETIME_VARIATION_DATE;
1973487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su        }
1983487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su    }
1993487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su}
200