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 android.content.Context; 20 import android.content.res.Resources; 21 import android.test.AndroidTestCase; 22 import android.view.ContextThemeWrapper; 23 import android.view.inputmethod.EditorInfo; 24 import android.view.inputmethod.InputMethodInfo; 25 import android.view.inputmethod.InputMethodSubtype; 26 27 import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; 28 import com.android.inputmethod.keyboard.KeyboardLayoutSet.Builder; 29 import com.android.inputmethod.latin.R; 30 import com.android.inputmethod.latin.RichInputMethodManager; 31 import com.android.inputmethod.latin.RichInputMethodSubtype; 32 import com.android.inputmethod.latin.common.Constants; 33 import com.android.inputmethod.latin.settings.Settings; 34 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; 35 import com.android.inputmethod.latin.utils.ResourceUtils; 36 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; 37 38 import java.util.ArrayList; 39 import java.util.Locale; 40 41 public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase { 42 // All input method subtypes of LatinIME. 43 private final ArrayList<InputMethodSubtype> mAllSubtypesList = new ArrayList<>(); 44 45 public interface SubtypeFilter { 46 public boolean accept(final InputMethodSubtype subtype); 47 } 48 49 public static final SubtypeFilter FILTER_IS_ASCII_CAPABLE = new SubtypeFilter() { 50 @Override 51 public boolean accept(InputMethodSubtype subtype) { 52 return InputMethodSubtypeCompatUtils.isAsciiCapable(subtype); 53 } 54 }; 55 56 public static final SubtypeFilter FILTER_IS_ADDITIONAL_SUBTYPE = new SubtypeFilter() { 57 @Override 58 public boolean accept(InputMethodSubtype subtype) { 59 return AdditionalSubtypeUtils.isAdditionalSubtype(subtype); 60 } 61 }; 62 63 private RichInputMethodManager mRichImm; 64 private InputMethodSubtype[] mSavedAdditionalSubtypes; 65 private int mScreenMetrics; 66 67 protected abstract int getKeyboardThemeForTests(); 68 69 @Override 70 protected void setUp() throws Exception { 71 super.setUp(); 72 final Context context = getContext(); 73 final Resources res = context.getResources(); 74 RichInputMethodManager.init(context); 75 mRichImm = RichInputMethodManager.getInstance(); 76 77 // Save and reset additional subtypes preference. 78 mSavedAdditionalSubtypes = mRichImm.getAdditionalSubtypes(); 79 final InputMethodSubtype[] predefinedAdditionalSubtypes = 80 AdditionalSubtypeUtils.createAdditionalSubtypesArray( 81 AdditionalSubtypeUtils.createPrefSubtypes( 82 res.getStringArray(R.array.predefined_subtypes))); 83 mRichImm.setAdditionalInputMethodSubtypes(predefinedAdditionalSubtypes); 84 85 final KeyboardTheme keyboardTheme = KeyboardTheme.searchKeyboardThemeById( 86 getKeyboardThemeForTests(), KeyboardTheme.KEYBOARD_THEMES); 87 setContext(new ContextThemeWrapper(getContext(), keyboardTheme.mStyleId)); 88 KeyboardLayoutSet.onKeyboardThemeChanged(); 89 90 mScreenMetrics = Settings.readScreenMetrics(res); 91 92 final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme(); 93 final int subtypeCount = imi.getSubtypeCount(); 94 for (int index = 0; index < subtypeCount; index++) { 95 mAllSubtypesList.add(imi.getSubtypeAt(index)); 96 } 97 } 98 99 @Override 100 protected void tearDown() throws Exception { 101 // Restore additional subtypes preference. 102 mRichImm.setAdditionalInputMethodSubtypes(mSavedAdditionalSubtypes); 103 super.tearDown(); 104 } 105 106 protected final ArrayList<InputMethodSubtype> getAllSubtypesList() { 107 return mAllSubtypesList; 108 } 109 110 protected final ArrayList<InputMethodSubtype> getSubtypesFilteredBy( 111 final SubtypeFilter filter) { 112 final ArrayList<InputMethodSubtype> list = new ArrayList<>(); 113 for (final InputMethodSubtype subtype : mAllSubtypesList) { 114 if (filter.accept(subtype)) { 115 list.add(subtype); 116 } 117 } 118 return list; 119 } 120 121 protected final boolean isPhone() { 122 return Constants.isPhone(mScreenMetrics); 123 } 124 125 protected final InputMethodSubtype getSubtype(final Locale locale, 126 final String keyboardLayout) { 127 for (final InputMethodSubtype subtype : mAllSubtypesList) { 128 final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype); 129 final String subtypeLayout = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); 130 if (locale.equals(subtypeLocale) && keyboardLayout.equals(subtypeLayout)) { 131 // Found subtype that matches locale and keyboard layout. 132 return subtype; 133 } 134 } 135 for (final InputMethodSubtype subtype : getSubtypesFilteredBy(FILTER_IS_ASCII_CAPABLE)) { 136 final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype); 137 if (locale.equals(subtypeLocale)) { 138 // Create additional subtype. 139 return AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( 140 locale.toString(), keyboardLayout); 141 } 142 } 143 throw new RuntimeException( 144 "Unknown subtype: locale=" + locale + " keyboardLayout=" + keyboardLayout); 145 } 146 147 protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, 148 final EditorInfo editorInfo) { 149 return createKeyboardLayoutSet(subtype, editorInfo, false /* voiceInputKeyEnabled */, 150 false /* languageSwitchKeyEnabled */, false /* splitLayoutEnabled */); 151 } 152 153 protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, 154 final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, 155 final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { 156 final Context context = getContext(); 157 final Resources res = context.getResources(); 158 final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res); 159 final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res); 160 final Builder builder = new Builder(context, editorInfo); 161 builder.setKeyboardGeometry(keyboardWidth, keyboardHeight) 162 .setSubtype(RichInputMethodSubtype.getRichInputMethodSubtype(subtype)) 163 .setVoiceInputKeyEnabled(voiceInputKeyEnabled) 164 .setLanguageSwitchKeyEnabled(languageSwitchKeyEnabled) 165 .setSplitLayoutEnabledByUser(splitLayoutEnabled); 166 return builder.build(); 167 } 168 } 169