1 /*
2  * Copyright (C) 2014 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 com.android.inputmethod.keyboard;
18 
19 import static com.android.inputmethod.compat.BuildCompatUtils.VERSION_CODES_LXX;
20 import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_ICS;
21 import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_KLP;
22 import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_LXX_DARK;
23 import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_LXX_LIGHT;
24 
25 import android.content.SharedPreferences;
26 import android.os.Build.VERSION_CODES;
27 import android.preference.PreferenceManager;
28 import android.test.AndroidTestCase;
29 import android.test.suitebuilder.annotation.SmallTest;
30 
31 @SmallTest
32 public class KeyboardThemeTests extends AndroidTestCase {
33     private SharedPreferences mPrefs;
34 
35     private static final int THEME_ID_NULL = -1;
36     private static final int THEME_ID_UNKNOWN = -2;
37     private static final int THEME_ID_ILLEGAL = -3;
38     private static final String ILLEGAL_THEME_ID_STRING = "ThisCausesNumberFormatExecption";
39 
40     @Override
setUp()41     protected void setUp() throws Exception {
42         super.setUp();
43         mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
44     }
45 
46     /*
47      * Helper functions.
48      */
49 
isValidKeyboardThemeId(final int themeId)50     private static boolean isValidKeyboardThemeId(final int themeId) {
51         switch (themeId) {
52         case THEME_ID_ICS:
53         case THEME_ID_KLP:
54         case THEME_ID_LXX_LIGHT:
55         case THEME_ID_LXX_DARK:
56             return true;
57         default:
58             return false;
59         }
60     }
61 
setKeyboardThemePreference(final String prefKey, final int themeId)62     private void setKeyboardThemePreference(final String prefKey, final int themeId) {
63         final String themeIdString = Integer.toString(themeId);
64         if (isValidKeyboardThemeId(themeId) || themeId == THEME_ID_UNKNOWN) {
65             // Set valid theme id to preference.
66             mPrefs.edit().putString(prefKey, themeIdString).apply();
67             return;
68         }
69         if (themeId == THEME_ID_NULL) {
70             // Simulate undefined preference.
71             mPrefs.edit().remove(prefKey).apply();
72             return;
73         }
74         // themeId == THEME_ID_ILLEGAL
75         // Simulate illegal format theme id in preference.
76         mPrefs.edit().putString(prefKey, ILLEGAL_THEME_ID_STRING).apply();
77     }
78 
assertKeyboardTheme(final int sdkVersion, final int expectedThemeId)79     private void assertKeyboardTheme(final int sdkVersion, final int expectedThemeId) {
80         assertEquals(expectedThemeId, KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion).mThemeId);
81     }
82 
83     /*
84      * Test keyboard theme preference on the same platform version and the same keyboard version.
85      */
86 
assertKeyboardThemePreference(final int sdkVersion, final int previousThemeId, final int expectedThemeId)87     private void assertKeyboardThemePreference(final int sdkVersion, final int previousThemeId,
88             final int expectedThemeId) {
89         // Clear preferences before testing.
90         setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL);
91         setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL);
92         // Set the preference of the sdkVersion to previousThemeId.
93         final String prefKey = KeyboardTheme.getPreferenceKey(sdkVersion);
94         setKeyboardThemePreference(prefKey, previousThemeId);
95         assertKeyboardTheme(sdkVersion, expectedThemeId);
96     }
97 
assertKeyboardThemePreferenceOnKlp(final int sdkVersion)98     private void assertKeyboardThemePreferenceOnKlp(final int sdkVersion) {
99         final int defaultThemeId = THEME_ID_KLP;
100         assertKeyboardThemePreference(sdkVersion, THEME_ID_NULL, defaultThemeId);
101         assertKeyboardThemePreference(sdkVersion, THEME_ID_ICS, THEME_ID_ICS);
102         assertKeyboardThemePreference(sdkVersion, THEME_ID_KLP, THEME_ID_KLP);
103         assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX_LIGHT, THEME_ID_LXX_LIGHT);
104         assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX_DARK, THEME_ID_LXX_DARK);
105         assertKeyboardThemePreference(sdkVersion, THEME_ID_UNKNOWN, defaultThemeId);
106         assertKeyboardThemePreference(sdkVersion, THEME_ID_ILLEGAL, defaultThemeId);
107     }
108 
testKeyboardThemePreferenceOnKlp()109     public void testKeyboardThemePreferenceOnKlp() {
110         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH);
111         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
112         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN);
113         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN_MR1);
114         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN_MR2);
115         assertKeyboardThemePreferenceOnKlp(VERSION_CODES.KITKAT);
116     }
117 
assertKeyboardThemePreferenceOnLxx(final int sdkVersion)118     private void assertKeyboardThemePreferenceOnLxx(final int sdkVersion) {
119         final int defaultThemeId = THEME_ID_LXX_LIGHT;
120         assertKeyboardThemePreference(sdkVersion, THEME_ID_NULL, defaultThemeId);
121         assertKeyboardThemePreference(sdkVersion, THEME_ID_ICS, THEME_ID_ICS);
122         assertKeyboardThemePreference(sdkVersion, THEME_ID_KLP, THEME_ID_KLP);
123         assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX_LIGHT, THEME_ID_LXX_LIGHT);
124         assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX_DARK, THEME_ID_LXX_DARK);
125         assertKeyboardThemePreference(sdkVersion, THEME_ID_UNKNOWN, defaultThemeId);
126         assertKeyboardThemePreference(sdkVersion, THEME_ID_ILLEGAL, defaultThemeId);
127     }
128 
testKeyboardThemePreferenceOnLxx()129     public void testKeyboardThemePreferenceOnLxx() {
130         assertKeyboardThemePreferenceOnLxx(VERSION_CODES_LXX);
131     }
132 
133     /*
134      * Test default keyboard theme based on the platform version.
135      */
136 
assertDefaultKeyboardTheme(final int sdkVersion, final int previousThemeId, final int expectedThemeId)137     private void assertDefaultKeyboardTheme(final int sdkVersion, final int previousThemeId,
138             final int expectedThemeId) {
139         final String oldPrefKey = KeyboardTheme.KLP_KEYBOARD_THEME_KEY;
140         setKeyboardThemePreference(oldPrefKey, previousThemeId);
141 
142         final KeyboardTheme defaultTheme =
143                 KeyboardTheme.getDefaultKeyboardTheme(mPrefs, sdkVersion);
144 
145         assertNotNull(defaultTheme);
146         assertEquals(expectedThemeId, defaultTheme.mThemeId);
147         if (sdkVersion <= VERSION_CODES.KITKAT) {
148             // Old preference must be retained if it is valid. Otherwise it must be pruned.
149             assertEquals(isValidKeyboardThemeId(previousThemeId), mPrefs.contains(oldPrefKey));
150             return;
151         }
152         // Old preference must be removed.
153         assertFalse(mPrefs.contains(oldPrefKey));
154     }
155 
assertDefaultKeyboardThemeOnKlp(final int sdkVersion)156     private void assertDefaultKeyboardThemeOnKlp(final int sdkVersion) {
157         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_KLP);
158         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ICS, THEME_ID_ICS);
159         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_KLP, THEME_ID_KLP);
160         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP);
161         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP);
162     }
163 
testDefaultKeyboardThemeOnKlp()164     public void testDefaultKeyboardThemeOnKlp() {
165         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH);
166         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
167         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN);
168         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN_MR1);
169         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN_MR2);
170         assertDefaultKeyboardThemeOnKlp(VERSION_CODES.KITKAT);
171     }
172 
assertDefaultKeyboardThemeOnLxx(final int sdkVersion)173     private void assertDefaultKeyboardThemeOnLxx(final int sdkVersion) {
174         // Forced to switch to LXX theme.
175         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT);
176         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ICS, THEME_ID_LXX_LIGHT);
177         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_KLP, THEME_ID_LXX_LIGHT);
178         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX_LIGHT);
179         assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX_LIGHT);
180     }
181 
testDefaultKeyboardThemeOnLxx()182     public void testDefaultKeyboardThemeOnLxx() {
183         assertDefaultKeyboardThemeOnLxx(VERSION_CODES_LXX);
184     }
185 
186     /*
187      * Test keyboard theme preference while upgrading the keyboard that doesn't support LXX theme
188      * to the keyboard that supports LXX theme.
189      */
190 
assertUpgradeKeyboardToLxxOn(final int sdkVersion, final int previousThemeId, final int expectedThemeId)191     private void assertUpgradeKeyboardToLxxOn(final int sdkVersion, final int previousThemeId,
192             final int expectedThemeId) {
193         setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, previousThemeId);
194         // Clean up new keyboard theme preference to simulate "upgrade to LXX keyboard".
195         setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL);
196 
197         final KeyboardTheme theme = KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion);
198 
199         assertNotNull(theme);
200         assertEquals(expectedThemeId, theme.mThemeId);
201         if (sdkVersion <= VERSION_CODES.KITKAT) {
202             // New preference must not exist.
203             assertFalse(mPrefs.contains(KeyboardTheme.LXX_KEYBOARD_THEME_KEY));
204             // Old preference must be retained if it is valid. Otherwise it must be pruned.
205             assertEquals(isValidKeyboardThemeId(previousThemeId),
206                     mPrefs.contains(KeyboardTheme.KLP_KEYBOARD_THEME_KEY));
207             if (isValidKeyboardThemeId(previousThemeId)) {
208                 // Old preference must have an expected value.
209                 assertEquals(mPrefs.getString(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, null),
210                         Integer.toString(expectedThemeId));
211             }
212             return;
213         }
214         // Old preference must be removed.
215         assertFalse(mPrefs.contains(KeyboardTheme.KLP_KEYBOARD_THEME_KEY));
216         // New preference must not exist.
217         assertFalse(mPrefs.contains(KeyboardTheme.LXX_KEYBOARD_THEME_KEY));
218     }
219 
assertUpgradeKeyboardToLxxOnKlp(final int sdkVersion)220     private void assertUpgradeKeyboardToLxxOnKlp(final int sdkVersion) {
221         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_NULL, THEME_ID_KLP);
222         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ICS, THEME_ID_ICS);
223         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_KLP, THEME_ID_KLP);
224         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP);
225         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP);
226     }
227 
228     // Upgrading keyboard on I,J and K.
testUpgradeKeyboardToLxxOnKlp()229     public void testUpgradeKeyboardToLxxOnKlp() {
230         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH);
231         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
232         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN);
233         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN_MR1);
234         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN_MR2);
235         assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.KITKAT);
236     }
237 
assertUpgradeKeyboardToLxxOnLxx(final int sdkVersion)238     private void assertUpgradeKeyboardToLxxOnLxx(final int sdkVersion) {
239         // Forced to switch to LXX theme.
240         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT);
241         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ICS, THEME_ID_LXX_LIGHT);
242         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_KLP, THEME_ID_LXX_LIGHT);
243         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX_LIGHT);
244         assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX_LIGHT);
245     }
246 
247     // Upgrading keyboard on L.
testUpgradeKeyboardToLxxOnLxx()248     public void testUpgradeKeyboardToLxxOnLxx() {
249         assertUpgradeKeyboardToLxxOnLxx(VERSION_CODES_LXX);
250     }
251 
252     /*
253      * Test keyboard theme preference while upgrading platform version.
254      */
255 
assertUpgradePlatformFromTo(final int oldSdkVersion, final int newSdkVersion, final int previousThemeId, final int expectedThemeId)256     private void assertUpgradePlatformFromTo(final int oldSdkVersion, final int newSdkVersion,
257             final int previousThemeId, final int expectedThemeId) {
258         if (newSdkVersion < oldSdkVersion) {
259             // No need to test.
260             return;
261         }
262         // Clean up preferences.
263         setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL);
264         setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL);
265 
266         final String oldPrefKey = KeyboardTheme.getPreferenceKey(oldSdkVersion);
267         setKeyboardThemePreference(oldPrefKey, previousThemeId);
268 
269         assertKeyboardTheme(newSdkVersion, expectedThemeId);
270     }
271 
assertUpgradePlatformFromKlpToKlp(final int oldSdkVersion, final int newSdkVersion)272     private void assertUpgradePlatformFromKlpToKlp(final int oldSdkVersion,
273             final int newSdkVersion) {
274         assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_KLP);
275         assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_ICS);
276         assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_KLP);
277         assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP);
278         assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP);
279     }
280 
assertUpgradePlatformToKlpFrom(final int oldSdkVersion)281     private void assertUpgradePlatformToKlpFrom(final int oldSdkVersion) {
282         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.ICE_CREAM_SANDWICH);
283         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
284         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN);
285         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN_MR1);
286         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN_MR2);
287         assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.KITKAT);
288     }
289 
290     // Update platform from I,J, and K to I,J, and K
testUpgradePlatformToKlpFromKlp()291     public void testUpgradePlatformToKlpFromKlp() {
292         assertUpgradePlatformToKlpFrom(VERSION_CODES.ICE_CREAM_SANDWICH);
293         assertUpgradePlatformToKlpFrom(VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
294         assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN);
295         assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN_MR1);
296         assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN_MR2);
297         assertUpgradePlatformToKlpFrom(VERSION_CODES.KITKAT);
298     }
299 
assertUpgradePlatformToLxxFrom(final int oldSdkVersion)300     private void assertUpgradePlatformToLxxFrom(final int oldSdkVersion) {
301         // Forced to switch to LXX theme.
302         final int newSdkVersion = VERSION_CODES_LXX;
303         assertUpgradePlatformFromTo(
304                 oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT);
305         assertUpgradePlatformFromTo(
306                 oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_LXX_LIGHT);
307         assertUpgradePlatformFromTo(
308                 oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_LXX_LIGHT);
309         assertUpgradePlatformFromTo(
310                 oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX_LIGHT);
311         assertUpgradePlatformFromTo(
312                 oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX_LIGHT);
313     }
314 
315     // Update platform from I,J, and K to L
testUpgradePlatformToLxx()316     public void testUpgradePlatformToLxx() {
317         assertUpgradePlatformToLxxFrom(VERSION_CODES.ICE_CREAM_SANDWICH);
318         assertUpgradePlatformToLxxFrom(VERSION_CODES.ICE_CREAM_SANDWICH_MR1);
319         assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN);
320         assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN_MR1);
321         assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN_MR2);
322         assertUpgradePlatformToLxxFrom(VERSION_CODES.KITKAT);
323     }
324 
325     // Update platform from L to L.
testUpgradePlatformToLxxFromLxx()326     public void testUpgradePlatformToLxxFromLxx() {
327         final int oldSdkVersion = VERSION_CODES_LXX;
328         final int newSdkVersion = VERSION_CODES_LXX;
329         assertUpgradePlatformFromTo(
330                 oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT);
331         assertUpgradePlatformFromTo(
332                 oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_ICS);
333         assertUpgradePlatformFromTo(
334                 oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_KLP);
335         assertUpgradePlatformFromTo(
336                 oldSdkVersion, newSdkVersion, THEME_ID_LXX_LIGHT, THEME_ID_LXX_LIGHT);
337         assertUpgradePlatformFromTo(
338                 oldSdkVersion, newSdkVersion, THEME_ID_LXX_DARK, THEME_ID_LXX_DARK);
339         assertUpgradePlatformFromTo(
340                 oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX_LIGHT);
341         assertUpgradePlatformFromTo(
342                 oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX_LIGHT);
343     }
344 }
345