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.test.ActivityInstrumentationTestCase2; 253487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Editable; 263487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Selection; 273487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Spannable; 283487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.SpannableString; 293487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.Spanned; 303487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.text.method.NumberKeyListener; 313487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.view.KeyEvent; 323487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.view.View; 333487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.widget.TextView; 343487313ff582d8a7ae2bf58e7379c4577522dd61Scott Suimport android.widget.TextView.BufferType; 353487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 36300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 373487313ff582d8a7ae2bf58e7379c4577522dd61Scott Supublic class NumberKeyListenerTest extends 383487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su ActivityInstrumentationTestCase2<KeyListenerStubActivity> { 39300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 403487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su private MockNumberKeyListener mNumberKeyListener; 413487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su private Activity mActivity; 423487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su private Instrumentation mInstrumentation; 433487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su private TextView mTextView; 443487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 453487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public NumberKeyListenerTest(){ 463487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su super("com.android.cts.stub", KeyListenerStubActivity.class); 473487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 483487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 493487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su @Override 503487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su protected void setUp() throws Exception { 513487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su super.setUp(); 523487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mActivity = getActivity(); 533487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mInstrumentation = getInstrumentation(); 543487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView = (TextView) mActivity.findViewById(R.id.keylistener_textview); 553487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 563487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 573487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su /** 583487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Check point: 593487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 1. Filter "Android test", return "". 603487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 2. Filter "12345", return null. 613487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 3. Filter "", return null. 623487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 4. Filter "12345 Android", return "12345". 633487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 5. Filter Spanned("12345 Android"), return Spanned("12345") and copy spans. 643487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su */ 653487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void testFilter() { 66300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu mNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS); 673487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su String source = "Android test"; 683487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su SpannableString dest = new SpannableString("012345"); 693487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("", mNumberKeyListener.filter(source, 0, source.length(), 703487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su dest, 0, dest.length()).toString()); 713487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 723487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su source = "12345"; 733487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su dest = new SpannableString("012345"); 743487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertNull(mNumberKeyListener.filter(source, 0, source.length(), dest, 0, dest.length())); 753487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 763487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su source = ""; 773487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su dest = new SpannableString("012345"); 783487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertNull(mNumberKeyListener.filter(source, 0, source.length(), dest, 0, dest.length())); 793487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 803487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su source = "12345 Android"; 813487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su dest = new SpannableString("012345 Android-test"); 823487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("12345", mNumberKeyListener.filter(source, 0, source.length(), 833487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su dest, 0, dest.length()).toString()); 843487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 853487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su Object what = new Object(); 863487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su Spannable spannableSource = new SpannableString("12345 Android"); 873487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su spannableSource.setSpan(what, 0, spannableSource.length(), Spanned.SPAN_POINT_POINT); 883487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su Spanned filtered = (Spanned) mNumberKeyListener.filter(spannableSource, 893487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 0, spannableSource.length(), dest, 0, dest.length()); 903487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("12345", filtered.toString()); 913487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals(Spanned.SPAN_POINT_POINT, filtered.getSpanFlags(what)); 923487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals(0, filtered.getSpanStart(what)); 933487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("12345".length(), filtered.getSpanEnd(what)); 943487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 953487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su try { 963487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mNumberKeyListener.filter(null, 0, 1, dest, 0, dest.length()); 973487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su fail("should throw NullPointerException."); 983487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } catch (NullPointerException e) { 993487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1003487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1013487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1023487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su /** 1033487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Check point: 1043487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * If one of the chars in the getAcceptedChars() can be generated by the keyCode of this 1053487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * key event, return the char; otherwise return '\0'. 1063487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su */ 1073487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void testLookup() { 108300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu mNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS); 1093487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su KeyEvent event1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0); 1103487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su SpannableString str = new SpannableString("012345"); 1113487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals('0', mNumberKeyListener.lookup(event1, str)); 1123487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 113300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu mNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.NOTHING); 114b540563eba88dee712c296c53cd8088bcc0368e7Brian Muramatsu KeyEvent event2 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A); 115b540563eba88dee712c296c53cd8088bcc0368e7Brian Muramatsu str = new SpannableString("ABCD"); 1163487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals('\0', mNumberKeyListener.lookup(event2, str)); 1173487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1183487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su try { 1193487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mNumberKeyListener.lookup(null, str); 1203487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su fail("should throw NullPointerException."); 1213487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } catch (NullPointerException e) { 1223487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su // expected. 1233487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1243487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1253487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1263487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void testOk() { 127300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu mNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS); 1283487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1293487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertTrue(mNumberKeyListener.callOk(mNumberKeyListener.getAcceptedChars(), '3')); 1303487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertFalse(mNumberKeyListener.callOk(mNumberKeyListener.getAcceptedChars(), 'e')); 1313487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1323487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su try { 1333487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mNumberKeyListener.callOk(null, 'm'); 1343487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su fail("should throw NullPointerException."); 1353487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } catch (NullPointerException e) { 1363487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1373487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1383487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1393487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su /** 1403487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * Check point: 1413487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 1. Press '0' key, '0' will be added to the text. 1423487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 2. Press an unaccepted key if it exists, it will not be added. 1433487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su * 3. remove NumberKeyListener and press '0' key, '0' will not be added. 1443487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su */ 1453487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void testPressKey() { 1463487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su final CharSequence text = "123456"; 147300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu final MockNumberKeyListener numberKeyListener = 148300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu new MockNumberKeyListener(MockNumberKeyListener.DIGITS); 1493487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1503487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mActivity.runOnUiThread(new Runnable() { 1513487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void run() { 1523487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView.setText(text, BufferType.EDITABLE); 1533487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView.setKeyListener(numberKeyListener); 1543487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView.requestFocus(); 1553487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su Selection.setSelection((Editable) mTextView.getText(), 0, 0); 1563487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1573487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su }); 1583487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mInstrumentation.waitForIdleSync(); 1593487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("123456", mTextView.getText().toString()); 1603487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su // press '0' key. 1613487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su sendKeys(KeyEvent.KEYCODE_0); 1623487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("0123456", mTextView.getText().toString()); 1633487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1643487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su // an unaccepted key if it exists. 165300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu int keyCode = TextMethodUtils.getUnacceptedKeyCode(MockNumberKeyListener.DIGITS); 1663487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su if (-1 != keyCode) { 1673487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su sendKeys(keyCode); 1683487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su // text of TextView will not be changed. 1693487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("0123456", mTextView.getText().toString()); 1703487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1713487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1723487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mActivity.runOnUiThread(new Runnable() { 1733487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public void run() { 1743487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView.setKeyListener(null); 1753487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mTextView.requestFocus(); 1763487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1773487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su }); 1783487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su mInstrumentation.waitForIdleSync(); 1793487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su // press '0' key. 1803487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su sendKeys(KeyEvent.KEYCODE_0); 1813487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su assertEquals("0123456", mTextView.getText().toString()); 1823487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 1833487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1843487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su private static class MockNumberKeyListener extends NumberKeyListener { 185300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 186300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu static final char[] DIGITS = 187300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 188300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 189300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu static final char[] NOTHING = new char[0]; 190300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 191300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu private final char[] mAcceptedChars; 192300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu 193300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu MockNumberKeyListener(char[] acceptedChars) { 194300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu this.mAcceptedChars = acceptedChars; 195300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu } 1963487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 1973487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su @Override 1983487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su protected char[] getAcceptedChars() { 199300d755fcaa7274f1570f53d34c7a657bc420ab6Brian Muramatsu return mAcceptedChars; 2003487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 2013487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 2023487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su @Override 2033487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su protected int lookup(KeyEvent event, Spannable content) { 2043487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su return super.lookup(event, content); 2053487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 2063487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 2073487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public boolean callOk(char[] accept, char c) { 2083487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su return NumberKeyListener.ok(accept, c); 2093487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 2103487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su 2113487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su public int getInputType() { 2123487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su return 0; 2133487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 2143487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su } 2153487313ff582d8a7ae2bf58e7379c4577522dd61Scott Su} 216