1 /*
2  * Copyright (C) 2008 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 
17 package android.text.method.cts;
18 
19 import android.text.Editable;
20 import android.text.Selection;
21 import android.text.Spannable;
22 import android.text.Spanned;
23 import android.text.method.cts.KeyListenerTestCase;
24 import android.text.method.DateKeyListener;
25 import android.text.method.MetaKeyKeyListener;
26 import android.view.KeyCharacterMap;
27 import android.view.KeyEvent;
28 import android.view.View;
29 import android.widget.ImageView;
30 
31 /**
32  * Test {@link MetaKeyKeyListener}.
33  */
34 public class MetaKeyKeyListenerTest extends KeyListenerTestCase {
testPressKey()35     public void testPressKey() {
36         final CharSequence str = "123456";
37         final MetaKeyKeyListener numberKeyListener = new DateKeyListener();
38         final View view = new ImageView(mInstrumentation.getTargetContext());
39         final Editable content = Editable.Factory.getInstance().newEditable(str);
40 
41         content.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
42         content.setSpan(Selection.SELECTION_END, 0, 0, Spanned.SPAN_POINT_POINT);
43         numberKeyListener.onKeyDown(view, content, KeyEvent.KEYCODE_0,
44                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0));
45         assertEquals('0', content.charAt(0));
46 
47         content.setSpan(Selection.SELECTION_START, 1, 1, Spanned.SPAN_POINT_POINT);
48         content.setSpan(Selection.SELECTION_END, 1, 1, Spanned.SPAN_POINT_POINT);
49         numberKeyListener.onKeyDown(view, content, KeyEvent.KEYCODE_2,
50                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_2));
51         assertEquals('2', content.charAt(1));
52 
53         content.setSpan(Selection.SELECTION_START, 3, 3, Spanned.SPAN_POINT_POINT);
54         content.setSpan(Selection.SELECTION_END, 3, 3, Spanned.SPAN_POINT_POINT);
55         numberKeyListener.onKeyDown(view, content, KeyEvent.KEYCODE_3,
56                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_3));
57         assertEquals('3', content.charAt(3));
58     }
59 
testReleaseKey()60     public void testReleaseKey() {
61         final CharSequence str = "123456";
62         final MetaKeyKeyListener numberKeyListener = new DateKeyListener();
63         final View view = new ImageView(mInstrumentation.getTargetContext());
64         final Editable content = Editable.Factory.getInstance().newEditable(str);
65 
66         content.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
67         content.setSpan(Selection.SELECTION_END, 0, 0, Spanned.SPAN_POINT_POINT);
68         numberKeyListener.onKeyUp(view, content, KeyEvent.KEYCODE_0,
69                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0));
70         assertEquals(str.charAt(0), content.charAt(0));
71 
72         content.setSpan(Selection.SELECTION_START, 1, 1, Spanned.SPAN_POINT_POINT);
73         content.setSpan(Selection.SELECTION_END, 1, 1, Spanned.SPAN_POINT_POINT);
74         numberKeyListener.onKeyUp(view, content, KeyEvent.KEYCODE_2,
75                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_2));
76         assertEquals(str.charAt(1), content.charAt(1));
77 
78         content.setSpan(Selection.SELECTION_START, 3, 3, Spanned.SPAN_POINT_POINT);
79         content.setSpan(Selection.SELECTION_END, 3, 3, Spanned.SPAN_POINT_POINT);
80         numberKeyListener.onKeyUp(view, content, KeyEvent.KEYCODE_3,
81                 new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_3));
82         assertEquals(str.charAt(3), content.charAt(3));
83     }
84 
testAdjustMetaAfterKeypress()85     public void testAdjustMetaAfterKeypress() {
86         CharSequence str = "123456";
87         Spannable content = Editable.Factory.getInstance().newEditable(str);
88         content.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
89         int len = str.length(); // for one line less than 100
90         content.setSpan( Selection.SELECTION_END, len, len, Spanned.SPAN_POINT_POINT);
91         MetaKeyKeyListener.adjustMetaAfterKeypress(content);
92         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_START));
93         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_END));
94 
95         str = "abc";
96         content = Editable.Factory.getInstance().newEditable(str);
97         content.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
98         len = str.length(); // for one line less than 100
99         content.setSpan( Selection.SELECTION_END, len, len, Spanned.SPAN_POINT_POINT);
100         MetaKeyKeyListener.adjustMetaAfterKeypress(content);
101         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_START));
102         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_END));
103 
104         str = "#@%#$^%^";
105         content = Editable.Factory.getInstance().newEditable(str);
106         content.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
107         len = str.length(); // for one line less than 100
108         content.setSpan( Selection.SELECTION_END, len, len, Spanned.SPAN_POINT_POINT);
109         MetaKeyKeyListener.adjustMetaAfterKeypress(content);
110         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_START));
111         assertEquals(Spanned.SPAN_POINT_POINT, content.getSpanFlags(Selection.SELECTION_END));
112     }
113 
testAdjustMetaAfterKeypress2()114     public void testAdjustMetaAfterKeypress2() {
115         long state = MetaKeyKeyListener.adjustMetaAfterKeypress(MetaKeyKeyListener.META_SHIFT_ON);
116         assertEquals(MetaKeyKeyListener.META_SHIFT_ON, state);
117 
118         state = MetaKeyKeyListener.adjustMetaAfterKeypress(MetaKeyKeyListener.META_ALT_ON);
119         assertEquals(MetaKeyKeyListener.META_ALT_ON, state);
120 
121         state = MetaKeyKeyListener.adjustMetaAfterKeypress(MetaKeyKeyListener.META_SYM_ON);
122         assertEquals(MetaKeyKeyListener.META_SYM_ON, state);
123 
124         state = MetaKeyKeyListener.adjustMetaAfterKeypress(0);
125         assertEquals(0, state);
126     }
127 
testResetMetaState()128     public void testResetMetaState() {
129         CharSequence str = "123456";
130         Spannable text = Editable.Factory.getInstance().newEditable(str);
131         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
132         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
133         MetaKeyKeyListener.resetMetaState(text);
134         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
135         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
136 
137         str = "abc";
138         text = Editable.Factory.getInstance().newEditable(str);
139         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
140         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
141         MetaKeyKeyListener.resetMetaState(text);
142         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
143         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
144 
145         str = "#@%#$^%^";
146         text = Editable.Factory.getInstance().newEditable(str);
147         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
148         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
149         MetaKeyKeyListener.resetMetaState(text);
150         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
151         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
152     }
153 
testGetMetaState()154     public void testGetMetaState() {
155         assertEquals(0, MetaKeyKeyListener.getMetaState("123456"));
156         assertEquals(0, MetaKeyKeyListener.getMetaState("abc"));
157         assertEquals(0, MetaKeyKeyListener.getMetaState("@#$$#^$^"));
158 
159         assertEquals(0,
160                      MetaKeyKeyListener.getMetaState("123456"),
161                      MetaKeyKeyListener.META_SHIFT_ON);
162         assertEquals(0,
163                      MetaKeyKeyListener.getMetaState("abc"),
164                      MetaKeyKeyListener.META_ALT_ON);
165         assertEquals(0,
166                      MetaKeyKeyListener.getMetaState("@#$$#^$^"),
167                      MetaKeyKeyListener.META_SYM_ON);
168 
169         assertEquals(0, MetaKeyKeyListener.getMetaState("123456", 0));
170         assertEquals(0, MetaKeyKeyListener.getMetaState("abc", -1));
171         assertEquals(0, MetaKeyKeyListener.getMetaState("@#$$#^$^", Integer.MAX_VALUE));
172 
173         assertEquals(0,
174                 MetaKeyKeyListener.getMetaState("123456", MetaKeyKeyListener.META_SHIFT_ON));
175         assertEquals(0, MetaKeyKeyListener.getMetaState("abc", MetaKeyKeyListener.META_ALT_ON));
176         assertEquals(0,
177                 MetaKeyKeyListener.getMetaState("@#$$#^$^", MetaKeyKeyListener.META_SYM_ON));
178     }
179 
testGetMetaState2()180     public void testGetMetaState2() {
181         assertEquals(0, MetaKeyKeyListener.getMetaState(0));
182         assertEquals(MetaKeyKeyListener.META_SHIFT_ON,
183                 MetaKeyKeyListener.getMetaState(MetaKeyKeyListener.META_SHIFT_ON));
184         assertEquals(MetaKeyKeyListener.META_CAP_LOCKED,
185                 MetaKeyKeyListener.getMetaState(MetaKeyKeyListener.META_CAP_LOCKED));
186 
187         assertEquals(0, MetaKeyKeyListener.getMetaState(0, MetaKeyKeyListener.META_SYM_ON));
188         assertEquals(1, MetaKeyKeyListener.getMetaState(MetaKeyKeyListener.META_SYM_ON,
189                 MetaKeyKeyListener.META_SYM_ON));
190         assertEquals(2, MetaKeyKeyListener.getMetaState(MetaKeyKeyListener.META_SYM_LOCKED,
191                 MetaKeyKeyListener.META_SYM_ON));
192     }
193 
testIsMetaTracker()194     public void testIsMetaTracker() {
195         assertFalse(MetaKeyKeyListener.isMetaTracker("123456", new Object()));
196         assertFalse(MetaKeyKeyListener.isMetaTracker("abc", new Object()));
197         assertFalse(MetaKeyKeyListener.isMetaTracker("@#$$#^$^", new Object()));
198     }
199 
testIsSelectingMetaTracker()200     public void testIsSelectingMetaTracker() {
201         assertFalse(MetaKeyKeyListener.isSelectingMetaTracker("123456", new Object()));
202         assertFalse(MetaKeyKeyListener.isSelectingMetaTracker("abc", new Object()));
203         assertFalse(MetaKeyKeyListener.isSelectingMetaTracker("@#$$#^$^", new Object()));
204     }
205 
testResetLockedMeta()206     public void testResetLockedMeta() {
207         MockMetaKeyKeyListener mockMetaKeyKeyListener = new MockMetaKeyKeyListener();
208 
209         MockSpannable str = new MockSpannable();
210         str.setSpan(new Object(), 0, 0, Spannable.SPAN_MARK_MARK
211                 | (4 << Spannable.SPAN_USER_SHIFT));
212         assertFalse(str.hasCalledRemoveSpan());
213         mockMetaKeyKeyListener.callResetLockedMeta(str);
214         assertTrue(str.hasCalledRemoveSpan());
215 
216         str = new MockSpannable();
217         str.setSpan(new Object(), 0, 0, Spannable.SPAN_MARK_POINT);
218         assertFalse(str.hasCalledRemoveSpan());
219         mockMetaKeyKeyListener.callResetLockedMeta(str);
220         assertFalse(str.hasCalledRemoveSpan());
221 
222         try {
223             mockMetaKeyKeyListener.callResetLockedMeta(null);
224             fail("should throw NullPointerException.");
225         } catch (NullPointerException e) {
226         }
227     }
228 
testResetLockedMeta2()229     public void testResetLockedMeta2() {
230         long state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_CAP_LOCKED);
231         assertEquals(0, state);
232 
233         state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_SHIFT_ON);
234         assertEquals(MetaKeyKeyListener.META_SHIFT_ON, state);
235 
236         state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_ALT_LOCKED);
237         assertEquals(0, state);
238 
239         state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_ALT_ON);
240         assertEquals(MetaKeyKeyListener.META_ALT_ON, state);
241 
242         state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_SYM_LOCKED);
243         assertEquals(0, state);
244 
245         state = MetaKeyKeyListener.resetLockedMeta(MetaKeyKeyListener.META_SYM_ON);
246         assertEquals(MetaKeyKeyListener.META_SYM_ON, state);
247     }
248 
testClearMetaKeyState()249     public void testClearMetaKeyState() {
250         final MetaKeyKeyListener numberKeyListener = new DateKeyListener();
251         CharSequence str = "123456";
252         Editable text = Editable.Factory.getInstance().newEditable(str);
253         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
254         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
255         numberKeyListener.clearMetaKeyState(null, text, MetaKeyKeyListener.META_SHIFT_ON);
256         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
257         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
258 
259         str = "abc";
260         text = Editable.Factory.getInstance().newEditable(str);
261         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
262         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
263         numberKeyListener.clearMetaKeyState(null, text, MetaKeyKeyListener.META_ALT_ON);
264         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
265         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
266 
267         str = "#@%#$^%^";
268         text = Editable.Factory.getInstance().newEditable(str);
269         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
270         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
271         numberKeyListener.clearMetaKeyState(null, text, MetaKeyKeyListener.META_SYM_ON);
272         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
273         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
274     }
275 
testClearMetaKeyState2()276     public void testClearMetaKeyState2() {
277         CharSequence str = "123456";
278         Editable text = Editable.Factory.getInstance().newEditable(str);
279         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
280         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
281         MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_SHIFT_ON);
282         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
283         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
284 
285         str = "abc";
286         text = Editable.Factory.getInstance().newEditable(str);
287         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
288         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
289         MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_ALT_ON);
290         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
291         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
292 
293         str = "#@%#$^%^";
294         text = Editable.Factory.getInstance().newEditable(str);
295         text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT);
296         text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT);
297         MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_SYM_ON);
298         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START));
299         assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END));
300     }
301 
testClearMetaKeyState3()302     public void testClearMetaKeyState3() {
303         final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
304         long state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_CAP_LOCKED,
305                 MetaKeyKeyListener.META_SHIFT_ON);
306         assertEquals(0, state);
307 
308         state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_SHIFT_ON,
309                 MetaKeyKeyListener.META_SHIFT_ON);
310         assertEquals(MetaKeyKeyListener.META_SHIFT_ON, state);
311 
312         state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_ALT_LOCKED,
313                 MetaKeyKeyListener.META_ALT_ON);
314         assertEquals(0, state);
315 
316         state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_ALT_ON,
317                 MetaKeyKeyListener.META_ALT_ON);
318         assertEquals(MetaKeyKeyListener.META_ALT_ON, state);
319 
320         state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_SYM_LOCKED,
321                 MetaKeyKeyListener.META_SYM_ON);
322         assertEquals(0, state);
323 
324         state = metaKeyKeyListener.clearMetaKeyState(MetaKeyKeyListener.META_SYM_ON,
325                 MetaKeyKeyListener.META_SYM_ON);
326         assertEquals(MetaKeyKeyListener.META_SYM_ON, state);
327     }
328 
testHandleKeyDown()329     public void testHandleKeyDown() {
330         KeyEvent fullEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SHIFT_LEFT,
331                 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
332         long state = MetaKeyKeyListener.handleKeyDown(MetaKeyKeyListener.META_CAP_LOCKED,
333                 KeyEvent.KEYCODE_SHIFT_LEFT, fullEvent);
334         assertEquals(0, state);
335     }
336 
testHandleKeyUp()337     public void testHandleKeyUp() {
338         KeyEvent fullEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SHIFT_LEFT,
339                 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
340         long state = MetaKeyKeyListener.handleKeyUp(MetaKeyKeyListener.META_CAP_LOCKED,
341                 KeyEvent.KEYCODE_SHIFT_LEFT, fullEvent);
342         assertEquals(0, state);
343     }
344 
345     /**
346      * A mocked {@link android.text.method.MetaKeyKeyListener} for testing purposes.
347      *
348      * Allows {@link MetaKeyKeyListenerTest} to call
349      * {@link android.text.method.MetaKeyKeyListener.resetLockedMeta(Spannable)}.
350      */
351     private class MockMetaKeyKeyListener extends MetaKeyKeyListener {
callResetLockedMeta(Spannable content)352         public void callResetLockedMeta(Spannable content) {
353             MetaKeyKeyListener.resetLockedMeta(content);
354         }
355     }
356 
357     /**
358      * A mocked {@link android.text.Spannable} for testing purposes.
359      */
360     private class MockSpannable implements Spannable {
361         private int mFlags;
362         private boolean mCalledRemoveSpan = false;
363 
hasCalledRemoveSpan()364         public boolean hasCalledRemoveSpan() {
365             return mCalledRemoveSpan;
366         }
367 
setSpan(Object what, int start, int end, int flags)368         public void setSpan(Object what, int start, int end, int flags) {
369             mFlags = flags;
370         }
371 
removeSpan(Object what)372         public void removeSpan(Object what) {
373             mCalledRemoveSpan = true;
374         }
375 
getSpans(int start, int end, Class<T> type)376         public <T> T[] getSpans(int start, int end, Class<T> type) {
377             return null;
378         }
379 
getSpanStart(Object tag)380         public int getSpanStart(Object tag) {
381             return 0;
382         }
383 
getSpanEnd(Object tag)384         public int getSpanEnd(Object tag) {
385             return 0;
386         }
387 
getSpanFlags(Object tag)388         public int getSpanFlags(Object tag) {
389             return mFlags;
390         }
391 
392         @SuppressWarnings("unchecked")
nextSpanTransition(int start, int limit, Class type)393         public int nextSpanTransition(int start, int limit, Class type) {
394             return 0;
395         }
396 
charAt(int index)397         public char charAt(int index) {
398             return 0;
399         }
400 
length()401         public int length() {
402             return 0;
403         }
404 
subSequence(int start, int end)405         public CharSequence subSequence(int start, int end) {
406             return null;
407         }
408     }
409 }
410