1/*
2 * Copyright (C) 2012 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
17package com.android.inputmethod.keyboard.internal;
18
19import android.test.AndroidTestCase;
20
21import com.android.inputmethod.latin.Constants;
22
23public class KeyboardStateTestsBase extends AndroidTestCase
24        implements MockKeyboardSwitcher.MockConstants {
25    protected MockKeyboardSwitcher mSwitcher;
26
27    @Override
28    protected void setUp() throws Exception {
29        super.setUp();
30
31        mSwitcher = new MockKeyboardSwitcher();
32        mSwitcher.setAutoCapsMode(CAP_MODE_OFF);
33
34        loadKeyboard(ALPHABET_UNSHIFTED);
35    }
36
37    /**
38     * Set auto caps mode.
39     *
40     * @param autoCaps the auto cap mode.
41     */
42    public void setAutoCapsMode(final int autoCaps) {
43        mSwitcher.setAutoCapsMode(autoCaps);
44    }
45
46    private static void assertLayout(final String message, final int expected, final int actual) {
47        assertTrue(message + ": expected=" + MockKeyboardSwitcher.getLayoutName(expected)
48                + " actual=" + MockKeyboardSwitcher.getLayoutName(actual),
49                expected == actual);
50    }
51
52    /**
53     * Emulate update keyboard shift state.
54     *
55     * @param afterUpdate the keyboard state after updating the keyboard shift state.
56     */
57    public void updateShiftState(final int afterUpdate) {
58        mSwitcher.updateShiftState();
59        assertLayout("afterUpdate", afterUpdate, mSwitcher.getLayoutId());
60    }
61
62    /**
63     * Emulate load default keyboard.
64     *
65     * @param afterLoad the keyboard state after loading default keyboard.
66     */
67    public void loadKeyboard(final int afterLoad) {
68        mSwitcher.loadKeyboard();
69        mSwitcher.updateShiftState();
70        assertLayout("afterLoad", afterLoad, mSwitcher.getLayoutId());
71    }
72
73    /**
74     * Emulate rotate device.
75     *
76     * @param afterRotate the keyboard state after rotating device.
77     */
78    public void rotateDevice(final int afterRotate) {
79        mSwitcher.saveKeyboardState();
80        mSwitcher.loadKeyboard();
81        assertLayout("afterRotate", afterRotate, mSwitcher.getLayoutId());
82    }
83
84    private void pressKeyWithoutTimerExpire(final int code, final boolean isSinglePointer,
85            final int afterPress) {
86        mSwitcher.onPressKey(code, isSinglePointer);
87        assertLayout("afterPress", afterPress, mSwitcher.getLayoutId());
88    }
89
90    /**
91     * Emulate key press.
92     *
93     * @param code the key code to press.
94     * @param afterPress the keyboard state after pressing the key.
95     */
96    public void pressKey(final int code, final int afterPress) {
97        mSwitcher.expireDoubleTapTimeout();
98        pressKeyWithoutTimerExpire(code, true, afterPress);
99    }
100
101    /**
102     * Emulate key release and register.
103     *
104     * @param code the key code to release and register
105     * @param afterRelease the keyboard state after releasing the key.
106     */
107    public void releaseKey(final int code, final int afterRelease) {
108        mSwitcher.onCodeInput(code);
109        mSwitcher.onReleaseKey(code, NOT_SLIDING);
110        assertLayout("afterRelease", afterRelease, mSwitcher.getLayoutId());
111    }
112
113    /**
114     * Emulate key press and release.
115     *
116     * @param code the key code to press and release.
117     * @param afterPress the keyboard state after pressing the key.
118     * @param afterRelease the keyboard state after releasing the key.
119     */
120    public void pressAndReleaseKey(final int code, final int afterPress, final int afterRelease) {
121        pressKey(code, afterPress);
122        releaseKey(code, afterRelease);
123    }
124
125    /**
126     * Emulate chording key press.
127     *
128     * @param code the chording key code.
129     * @param afterPress the keyboard state after pressing chording key.
130     */
131    public void chordingPressKey(final int code, final int afterPress) {
132        mSwitcher.expireDoubleTapTimeout();
133        pressKeyWithoutTimerExpire(code, false, afterPress);
134    }
135
136    /**
137     * Emulate chording key release.
138     *
139     * @param code the cording key code.
140     * @param afterRelease the keyboard state after releasing chording key.
141     */
142    public void chordingReleaseKey(final int code, final int afterRelease) {
143        mSwitcher.onCodeInput(code);
144        mSwitcher.onReleaseKey(code, NOT_SLIDING);
145        assertLayout("afterRelease", afterRelease, mSwitcher.getLayoutId());
146    }
147
148    /**
149     * Emulate chording key press and release.
150     *
151     * @param code the chording key code.
152     * @param afterPress the keyboard state after pressing chording key.
153     * @param afterRelease the keyboard state after releasing chording key.
154     */
155    public void chordingPressAndReleaseKey(final int code, final int afterPress,
156            final int afterRelease) {
157        chordingPressKey(code, afterPress);
158        chordingReleaseKey(code, afterRelease);
159    }
160
161    /**
162     * Emulate start of the sliding key input.
163     *
164     * @param code the key code to start sliding.
165     * @param afterPress the keyboard state after pressing the key.
166     * @param afterSlide the keyboard state after releasing the key with sliding input.
167     */
168    public void pressAndSlideFromKey(final int code, final int afterPress, final int afterSlide) {
169        pressKey(code, afterPress);
170        mSwitcher.onReleaseKey(code, SLIDING);
171        assertLayout("afterSlide", afterSlide, mSwitcher.getLayoutId());
172    }
173
174    /**
175     * Emulate end of the sliding key input.
176     *
177     * @param code the key code to stop sliding.
178     * @param afterPress the keyboard state after pressing the key.
179     * @param afterSlide the keyboard state after releasing the key and stop sliding.
180     */
181    public void stopSlidingOnKey(final int code, final int afterPress, final int afterSlide) {
182        pressKey(code, afterPress);
183        mSwitcher.onCodeInput(code);
184        mSwitcher.onReleaseKey(code, NOT_SLIDING);
185        mSwitcher.onFinishSlidingInput();
186        assertLayout("afterSlide", afterSlide, mSwitcher.getLayoutId());
187    }
188
189    /**
190     * Emulate cancel the sliding key input.
191     *
192     * @param afterCancelSliding the keyboard state after canceling sliding input.
193     */
194    public void stopSlidingAndCancel(final int afterCancelSliding) {
195        mSwitcher.onFinishSlidingInput();
196        assertLayout("afterCancelSliding", afterCancelSliding, mSwitcher.getLayoutId());
197    }
198
199    /**
200     * Emulate long press shift key.
201     *
202     * @param afterPress the keyboard state after pressing shift key.
203     * @param afterLongPress the keyboard state after long press fired.
204     */
205    public void longPressShiftKey(final int afterPress, final int afterLongPress) {
206        // Long press shift key will register {@link Constants#CODE_CAPS_LOCK}. See
207        // {@link R.xml#key_styles_common} and its baseForShiftKeyStyle. We thus emulate the
208        // behavior that is implemented in {@link MainKeyboardView#onLongPress(PointerTracker)}.
209        pressKey(Constants.CODE_SHIFT, afterPress);
210        mSwitcher.onPressKey(Constants.CODE_CAPSLOCK, true /* isSinglePointer */);
211        mSwitcher.onCodeInput(Constants.CODE_CAPSLOCK);
212        assertLayout("afterLongPress", afterLongPress, mSwitcher.getLayoutId());
213    }
214
215    /**
216     * Emulate long press shift key and release.
217     *
218     * @param afterPress the keyboard state after pressing shift key.
219     * @param afterLongPress the keyboard state after long press fired.
220     * @param afterRelease the keyboard state after shift key is released.
221     */
222    public void longPressAndReleaseShiftKey(final int afterPress, final int afterLongPress,
223            final int afterRelease) {
224        // Long press shift key will register {@link Constants#CODE_CAPS_LOCK}. See
225        // {@link R.xml#key_styles_common} and its baseForShiftKeyStyle. We thus emulate the
226        // behavior that is implemented in {@link MainKeyboardView#onLongPress(PointerTracker)}.
227        longPressShiftKey(afterPress, afterLongPress);
228        releaseKey(Constants.CODE_CAPSLOCK, afterRelease);
229    }
230
231    /**
232     * Emulate the second press of the double tap.
233     *
234     * @param code the key code to double tap.
235     * @param afterPress the keyboard state after pressing the second tap.
236     */
237    public void secondPressKey(final int code, final int afterPress) {
238        pressKeyWithoutTimerExpire(code, true, afterPress);
239    }
240
241    /**
242     * Emulate the second tap of the double tap.
243     *
244     * @param code the key code to double tap.
245     * @param afterPress the keyboard state after pressing the second tap.
246     * @param afterRelease the keyboard state after releasing the second tap.
247     */
248    public void secondPressAndReleaseKey(final int code, final int afterPress,
249            final int afterRelease) {
250        secondPressKey(code, afterPress);
251        releaseKey(code, afterRelease);
252    }
253}
254