1 /* 2 * Copyright (C) 2013 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.latin; 18 19 import android.content.Context; 20 import android.util.LruCache; 21 22 import com.android.inputmethod.annotations.UsedForTesting; 23 import com.android.inputmethod.keyboard.Keyboard; 24 import com.android.inputmethod.latin.common.ComposedData; 25 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; 26 import com.android.inputmethod.latin.utils.SuggestionResults; 27 28 import java.io.File; 29 import java.util.ArrayList; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Locale; 33 import java.util.Map; 34 import java.util.concurrent.TimeUnit; 35 36 import javax.annotation.Nonnull; 37 import javax.annotation.Nullable; 38 39 /** 40 * Interface that facilitates interaction with different kinds of dictionaries. Provides APIs to 41 * instantiate and select the correct dictionaries (based on language or account), update entries 42 * and fetch suggestions. Currently AndroidSpellCheckerService and LatinIME both use 43 * DictionaryFacilitator as a client for interacting with dictionaries. 44 */ 45 public interface DictionaryFacilitator { 46 47 public static final String[] ALL_DICTIONARY_TYPES = new String[] { 48 Dictionary.TYPE_MAIN, 49 Dictionary.TYPE_CONTACTS, 50 Dictionary.TYPE_USER_HISTORY, 51 Dictionary.TYPE_USER}; 52 53 public static final String[] DYNAMIC_DICTIONARY_TYPES = new String[] { 54 Dictionary.TYPE_CONTACTS, 55 Dictionary.TYPE_USER_HISTORY, 56 Dictionary.TYPE_USER}; 57 58 /** 59 * The facilitator will put words into the cache whenever it decodes them. 60 * @param cache 61 */ setValidSpellingWordReadCache(final LruCache<String, Boolean> cache)62 void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache); 63 64 /** 65 * The facilitator will get words from the cache whenever it needs to check their spelling. 66 * @param cache 67 */ setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache)68 void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache); 69 70 /** 71 * Returns whether this facilitator is exactly for this locale. 72 * 73 * @param locale the locale to test against 74 */ isForLocale(final Locale locale)75 boolean isForLocale(final Locale locale); 76 77 /** 78 * Returns whether this facilitator is exactly for this account. 79 * 80 * @param account the account to test against. 81 */ isForAccount(@ullable final String account)82 boolean isForAccount(@Nullable final String account); 83 84 interface DictionaryInitializationListener { onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable)85 void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); 86 } 87 88 /** 89 * Called every time {@link LatinIME} starts on a new text field. 90 * Dot not affect {@link AndroidSpellCheckerService}. 91 * 92 * WARNING: The service methods that call start/finish are very spammy. 93 */ onStartInput()94 void onStartInput(); 95 96 /** 97 * Called every time the {@link LatinIME} finishes with the current text field. 98 * May be followed by {@link #onStartInput} again in another text field, 99 * or it may be done for a while. 100 * Dot not affect {@link AndroidSpellCheckerService}. 101 * 102 * WARNING: The service methods that call start/finish are very spammy. 103 */ onFinishInput(Context context)104 void onFinishInput(Context context); 105 isActive()106 boolean isActive(); 107 getLocale()108 Locale getLocale(); 109 usesContacts()110 boolean usesContacts(); 111 getAccount()112 String getAccount(); 113 resetDictionaries( final Context context, final Locale newLocale, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, @Nullable final String account, final String dictNamePrefix, @Nullable final DictionaryInitializationListener listener)114 void resetDictionaries( 115 final Context context, 116 final Locale newLocale, 117 final boolean useContactsDict, 118 final boolean usePersonalizedDicts, 119 final boolean forceReloadMainDictionary, 120 @Nullable final String account, 121 final String dictNamePrefix, 122 @Nullable final DictionaryInitializationListener listener); 123 124 @UsedForTesting resetDictionariesForTesting( final Context context, final Locale locale, final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, final Map<String, Map<String, String>> additionalDictAttributes, @Nullable final String account)125 void resetDictionariesForTesting( 126 final Context context, 127 final Locale locale, 128 final ArrayList<String> dictionaryTypes, 129 final HashMap<String, File> dictionaryFiles, 130 final Map<String, Map<String, String>> additionalDictAttributes, 131 @Nullable final String account); 132 closeDictionaries()133 void closeDictionaries(); 134 135 @UsedForTesting getSubDictForTesting(final String dictName)136 ExpandableBinaryDictionary getSubDictForTesting(final String dictName); 137 138 // The main dictionaries are loaded asynchronously. Don't cache the return value 139 // of these methods. hasAtLeastOneInitializedMainDictionary()140 boolean hasAtLeastOneInitializedMainDictionary(); 141 hasAtLeastOneUninitializedMainDictionary()142 boolean hasAtLeastOneUninitializedMainDictionary(); 143 waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)144 void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit) 145 throws InterruptedException; 146 147 @UsedForTesting waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)148 void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit) 149 throws InterruptedException; 150 addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, final boolean blockPotentiallyOffensive)151 void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, 152 @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, 153 final boolean blockPotentiallyOffensive); 154 unlearnFromUserHistory(final String word, @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, final int eventType)155 void unlearnFromUserHistory(final String word, 156 @Nonnull final NgramContext ngramContext, final long timeStampInSeconds, 157 final int eventType); 158 159 // TODO: Revise the way to fusion suggestion results. getSuggestionResults(final ComposedData composedData, final NgramContext ngramContext, @Nonnull final Keyboard keyboard, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final int inputStyle)160 @Nonnull SuggestionResults getSuggestionResults(final ComposedData composedData, 161 final NgramContext ngramContext, @Nonnull final Keyboard keyboard, 162 final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, 163 final int inputStyle); 164 isValidSpellingWord(final String word)165 boolean isValidSpellingWord(final String word); 166 isValidSuggestionWord(final String word)167 boolean isValidSuggestionWord(final String word); 168 clearUserHistoryDictionary(final Context context)169 boolean clearUserHistoryDictionary(final Context context); 170 dump(final Context context)171 String dump(final Context context); 172 dumpDictionaryForDebug(final String dictName)173 void dumpDictionaryForDebug(final String dictName); 174 getDictionaryStats(final Context context)175 @Nonnull List<DictionaryStats> getDictionaryStats(final Context context); 176 } 177