KeyboardTheme.java revision 78cff10f8d317641dd3531cce04e74502be8ad44
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
17package com.android.inputmethod.keyboard;
18
19import android.content.SharedPreferences;
20import android.os.Build.VERSION_CODES;
21import android.util.Log;
22
23import com.android.inputmethod.annotations.UsedForTesting;
24import com.android.inputmethod.compat.BuildCompatUtils;
25import com.android.inputmethod.latin.R;
26
27import java.util.Arrays;
28
29public final class KeyboardTheme implements Comparable<KeyboardTheme> {
30    private static final String TAG = KeyboardTheme.class.getSimpleName();
31
32    static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916";
33    static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509";
34
35    public static final int THEME_ID_ICS = 0;
36    public static final int THEME_ID_KLP = 2;
37    public static final int THEME_ID_LXX_LIGHT = 3;
38    public static final int THEME_ID_LXX_DARK = 4;
39    public static final int DEFAULT_THEME_ID = THEME_ID_KLP;
40
41    private static final KeyboardTheme[] KEYBOARD_THEMES = {
42        new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS,
43                // This has never been selected because we support ICS or later.
44                VERSION_CODES.BASE),
45        new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP,
46                // Default theme for ICS, JB, and KLP.
47                VERSION_CODES.ICE_CREAM_SANDWICH),
48        new KeyboardTheme(THEME_ID_LXX_LIGHT, R.style.KeyboardTheme_LXX_Light,
49                // Default theme for LXX.
50                BuildCompatUtils.VERSION_CODES_LXX),
51        new KeyboardTheme(THEME_ID_LXX_DARK, R.style.KeyboardTheme_LXX_Dark,
52                VERSION_CODES.BASE),
53    };
54
55    static {
56        // Sort {@link #KEYBOARD_THEME} by descending order of {@link #mMinApiVersion}.
57        Arrays.sort(KEYBOARD_THEMES);
58    }
59
60    public final int mThemeId;
61    public final int mStyleId;
62    private final int mMinApiVersion;
63
64    // Note: The themeId should be aligned with "themeId" attribute of Keyboard style
65    // in values/themes-<style>.xml.
66    private KeyboardTheme(final int themeId, final int styleId, final int minApiVersion) {
67        mThemeId = themeId;
68        mStyleId = styleId;
69        mMinApiVersion = minApiVersion;
70    }
71
72    @Override
73    public int compareTo(final KeyboardTheme rhs) {
74        if (mMinApiVersion > rhs.mMinApiVersion) return -1;
75        if (mMinApiVersion < rhs.mMinApiVersion) return 1;
76        return 0;
77    }
78
79    @Override
80    public boolean equals(final Object o) {
81        if (o == this) return true;
82        return (o instanceof KeyboardTheme) && ((KeyboardTheme)o).mThemeId == mThemeId;
83    }
84
85    @Override
86    public int hashCode() {
87        return mThemeId;
88    }
89
90    @UsedForTesting
91    static KeyboardTheme searchKeyboardThemeById(final int themeId) {
92        // TODO: This search algorithm isn't optimal if there are many themes.
93        for (final KeyboardTheme theme : KEYBOARD_THEMES) {
94            if (theme.mThemeId == themeId) {
95                return theme;
96            }
97        }
98        return null;
99    }
100
101    @UsedForTesting
102    static KeyboardTheme getDefaultKeyboardTheme(final SharedPreferences prefs,
103            final int sdkVersion) {
104        final String klpThemeIdString = prefs.getString(KLP_KEYBOARD_THEME_KEY, null);
105        if (klpThemeIdString != null) {
106            if (sdkVersion <= VERSION_CODES.KITKAT) {
107                try {
108                    final int themeId = Integer.parseInt(klpThemeIdString);
109                    final KeyboardTheme theme = searchKeyboardThemeById(themeId);
110                    if (theme != null) {
111                        return theme;
112                    }
113                    Log.w(TAG, "Unknown keyboard theme in KLP preference: " + klpThemeIdString);
114                } catch (final NumberFormatException e) {
115                    Log.w(TAG, "Illegal keyboard theme in KLP preference: " + klpThemeIdString, e);
116                }
117            }
118            // Remove old preference.
119            Log.i(TAG, "Remove KLP keyboard theme preference: " + klpThemeIdString);
120            prefs.edit().remove(KLP_KEYBOARD_THEME_KEY).apply();
121        }
122        // TODO: This search algorithm isn't optimal if there are many themes.
123        for (final KeyboardTheme theme : KEYBOARD_THEMES) {
124            if (sdkVersion >= theme.mMinApiVersion) {
125                return theme;
126            }
127        }
128        return searchKeyboardThemeById(DEFAULT_THEME_ID);
129    }
130
131    public static void saveKeyboardThemeId(final String themeIdString,
132            final SharedPreferences prefs) {
133        saveKeyboardThemeId(themeIdString, prefs, BuildCompatUtils.EFFECTIVE_SDK_INT);
134    }
135
136    @UsedForTesting
137    static String getPreferenceKey(final int sdkVersion) {
138        if (sdkVersion <= VERSION_CODES.KITKAT) {
139            return KLP_KEYBOARD_THEME_KEY;
140        }
141        return LXX_KEYBOARD_THEME_KEY;
142    }
143
144    @UsedForTesting
145    static void saveKeyboardThemeId(final String themeIdString,
146            final SharedPreferences prefs, final int sdkVersion) {
147        final String prefKey = getPreferenceKey(sdkVersion);
148        prefs.edit().putString(prefKey, themeIdString).apply();
149    }
150
151    public static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs) {
152        return getKeyboardTheme(prefs, BuildCompatUtils.EFFECTIVE_SDK_INT);
153    }
154
155    @UsedForTesting
156    static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion) {
157        final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null);
158        if (lxxThemeIdString == null) {
159            return getDefaultKeyboardTheme(prefs, sdkVersion);
160        }
161        try {
162            final int themeId = Integer.parseInt(lxxThemeIdString);
163            final KeyboardTheme theme = searchKeyboardThemeById(themeId);
164            if (theme != null) {
165                return theme;
166            }
167            Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString);
168        } catch (final NumberFormatException e) {
169            Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e);
170        }
171        // Remove preference that contains unknown or illegal theme id.
172        prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply();
173        return getDefaultKeyboardTheme(prefs, sdkVersion);
174    }
175}
176