KeyboardTheme.java revision 78cff10f8d317641dd3531cce04e74502be8ad44
1d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka/* 2d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * Copyright (C) 2014 The Android Open Source Project 3d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * 4d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * you may not use this file except in compliance with the License. 6d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * You may obtain a copy of the License at 7d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * 8d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * 10d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * See the License for the specific language governing permissions and 14d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka * limitations under the License. 15d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka */ 16d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka 17d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaokapackage com.android.inputmethod.keyboard; 18d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka 1921eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaokaimport android.content.SharedPreferences; 2059c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaokaimport android.os.Build.VERSION_CODES; 2121eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaokaimport android.util.Log; 2221eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 23c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaokaimport com.android.inputmethod.annotations.UsedForTesting; 2478cff10f8d317641dd3531cce04e74502be8ad44Tadashi G. Takaokaimport com.android.inputmethod.compat.BuildCompatUtils; 25d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaokaimport com.android.inputmethod.latin.R; 2659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka 2759c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaokaimport java.util.Arrays; 28d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka 29c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaokapublic final class KeyboardTheme implements Comparable<KeyboardTheme> { 3021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka private static final String TAG = KeyboardTheme.class.getSimpleName(); 3121eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 323b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916"; 333b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509"; 3459c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka 35c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka public static final int THEME_ID_ICS = 0; 36c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka public static final int THEME_ID_KLP = 2; 37f9f409530ccdc975ef965b1d1fee44bbd341d718Tadashi G. Takaoka public static final int THEME_ID_LXX_LIGHT = 3; 38f9f409530ccdc975ef965b1d1fee44bbd341d718Tadashi G. Takaoka public static final int THEME_ID_LXX_DARK = 4; 39c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka public static final int DEFAULT_THEME_ID = THEME_ID_KLP; 4021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 4121eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka private static final KeyboardTheme[] KEYBOARD_THEMES = { 4259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS, 43c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka // This has never been selected because we support ICS or later. 443b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka VERSION_CODES.BASE), 4559c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP, 46c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka // Default theme for ICS, JB, and KLP. 473b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka VERSION_CODES.ICE_CREAM_SANDWICH), 48f9f409530ccdc975ef965b1d1fee44bbd341d718Tadashi G. Takaoka new KeyboardTheme(THEME_ID_LXX_LIGHT, R.style.KeyboardTheme_LXX_Light, 49c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka // Default theme for LXX. 5078cff10f8d317641dd3531cce04e74502be8ad44Tadashi G. Takaoka BuildCompatUtils.VERSION_CODES_LXX), 51f9f409530ccdc975ef965b1d1fee44bbd341d718Tadashi G. Takaoka new KeyboardTheme(THEME_ID_LXX_DARK, R.style.KeyboardTheme_LXX_Dark, 52f9f409530ccdc975ef965b1d1fee44bbd341d718Tadashi G. Takaoka VERSION_CODES.BASE), 53d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka }; 54c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka 5559c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka static { 5659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka // Sort {@link #KEYBOARD_THEME} by descending order of {@link #mMinApiVersion}. 57c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka Arrays.sort(KEYBOARD_THEMES); 5859c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 59d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka 60d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka public final int mThemeId; 61d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka public final int mStyleId; 62c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka private final int mMinApiVersion; 63d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka 64d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka // Note: The themeId should be aligned with "themeId" attribute of Keyboard style 6559c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka // in values/themes-<style>.xml. 6659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka private KeyboardTheme(final int themeId, final int styleId, final int minApiVersion) { 67d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka mThemeId = themeId; 68d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka mStyleId = styleId; 6959c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka mMinApiVersion = minApiVersion; 7059c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 7159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka 7259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka @Override 73c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka public int compareTo(final KeyboardTheme rhs) { 74c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka if (mMinApiVersion > rhs.mMinApiVersion) return -1; 75c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka if (mMinApiVersion < rhs.mMinApiVersion) return 1; 76c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka return 0; 77c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka } 78c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka 79c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @Override 8059c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka public boolean equals(final Object o) { 8159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka if (o == this) return true; 8259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return (o instanceof KeyboardTheme) && ((KeyboardTheme)o).mThemeId == mThemeId; 83d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka } 8421eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 8559c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka @Override 8659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka public int hashCode() { 8759c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return mThemeId; 8859c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 8959c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka 90c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @UsedForTesting 91c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka static KeyboardTheme searchKeyboardThemeById(final int themeId) { 9221eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka // TODO: This search algorithm isn't optimal if there are many themes. 9321eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka for (final KeyboardTheme theme : KEYBOARD_THEMES) { 9421eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka if (theme.mThemeId == themeId) { 9521eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka return theme; 9621eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 9721eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 9821eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka return null; 9921eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 10021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 101c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @UsedForTesting 10259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka static KeyboardTheme getDefaultKeyboardTheme(final SharedPreferences prefs, 10359c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka final int sdkVersion) { 1043b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka final String klpThemeIdString = prefs.getString(KLP_KEYBOARD_THEME_KEY, null); 1053b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka if (klpThemeIdString != null) { 10659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka if (sdkVersion <= VERSION_CODES.KITKAT) { 10759c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka try { 1083b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka final int themeId = Integer.parseInt(klpThemeIdString); 10959c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka final KeyboardTheme theme = searchKeyboardThemeById(themeId); 11059c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka if (theme != null) { 11159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return theme; 11259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 1133b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka Log.w(TAG, "Unknown keyboard theme in KLP preference: " + klpThemeIdString); 11459c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } catch (final NumberFormatException e) { 1153b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka Log.w(TAG, "Illegal keyboard theme in KLP preference: " + klpThemeIdString, e); 11659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 11759c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 1183b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka // Remove old preference. 1193b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka Log.i(TAG, "Remove KLP keyboard theme preference: " + klpThemeIdString); 1203b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka prefs.edit().remove(KLP_KEYBOARD_THEME_KEY).apply(); 12159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 12259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka // TODO: This search algorithm isn't optimal if there are many themes. 12359c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka for (final KeyboardTheme theme : KEYBOARD_THEMES) { 12459c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka if (sdkVersion >= theme.mMinApiVersion) { 12559c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return theme; 12659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 12759c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 12859c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return searchKeyboardThemeById(DEFAULT_THEME_ID); 12959c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka } 13059c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka 13159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka public static void saveKeyboardThemeId(final String themeIdString, 13259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka final SharedPreferences prefs) { 13378cff10f8d317641dd3531cce04e74502be8ad44Tadashi G. Takaoka saveKeyboardThemeId(themeIdString, prefs, BuildCompatUtils.EFFECTIVE_SDK_INT); 1343b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka } 1353b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka 136c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @UsedForTesting 1373b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka static String getPreferenceKey(final int sdkVersion) { 1383b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka if (sdkVersion <= VERSION_CODES.KITKAT) { 1393b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka return KLP_KEYBOARD_THEME_KEY; 1403b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka } 1413b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka return LXX_KEYBOARD_THEME_KEY; 1423b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka } 1433b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka 144c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @UsedForTesting 145c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka static void saveKeyboardThemeId(final String themeIdString, 146c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka final SharedPreferences prefs, final int sdkVersion) { 1473b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka final String prefKey = getPreferenceKey(sdkVersion); 1483b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka prefs.edit().putString(prefKey, themeIdString).apply(); 14921eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 15021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka 15121eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka public static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs) { 15278cff10f8d317641dd3531cce04e74502be8ad44Tadashi G. Takaoka return getKeyboardTheme(prefs, BuildCompatUtils.EFFECTIVE_SDK_INT); 1533b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka } 1543b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka 155c5dc74067385f9ab6ec3086825d0b369c26a1ea3Tadashi G. Takaoka @UsedForTesting 1563b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion) { 1573b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null); 1583b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka if (lxxThemeIdString == null) { 15959c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return getDefaultKeyboardTheme(prefs, sdkVersion); 16021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 16121eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka try { 1623b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka final int themeId = Integer.parseInt(lxxThemeIdString); 16359c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka final KeyboardTheme theme = searchKeyboardThemeById(themeId); 16421eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka if (theme != null) { 16521eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka return theme; 16621eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 1673b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString); 16821eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } catch (final NumberFormatException e) { 1693b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e); 17021eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 1713b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka // Remove preference that contains unknown or illegal theme id. 1723b12718537f40b262e5eeb5c8168d69b2afa6955Tadashi G. Takaoka prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply(); 17359c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka return getDefaultKeyboardTheme(prefs, sdkVersion); 17421eafd7910182a31372fb92895f057cff28a8480Tadashi G. Takaoka } 175d6aa94e6b5fd7abc25a8d21857211ffd0852b33aTadashi G. Takaoka} 176