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.latin; 18 19 import java.util.Locale; 20 import java.util.concurrent.TimeUnit; 21 22 import android.content.Context; 23 import android.util.Log; 24 25 /** 26 * Cache for dictionary facilitators of multiple locales. 27 * This class automatically creates and releases up to 3 facilitator instances using LRU policy. 28 */ 29 public class DictionaryFacilitatorLruCache { 30 private static final String TAG = "DictionaryFacilitatorLruCache"; 31 private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000; 32 private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5; 33 34 private final Context mContext; 35 private final String mDictionaryNamePrefix; 36 private final Object mLock = new Object(); 37 private final DictionaryFacilitator mDictionaryFacilitator; 38 private boolean mUseContactsDictionary; 39 private Locale mLocale; 40 DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix)41 public DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix) { 42 mContext = context; 43 mDictionaryNamePrefix = dictionaryNamePrefix; 44 mDictionaryFacilitator = DictionaryFacilitatorProvider.getDictionaryFacilitator( 45 true /* isNeededForSpellChecking */); 46 } 47 waitForLoadingMainDictionary( final DictionaryFacilitator dictionaryFacilitator)48 private static void waitForLoadingMainDictionary( 49 final DictionaryFacilitator dictionaryFacilitator) { 50 for (int i = 0; i < MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT; i++) { 51 try { 52 dictionaryFacilitator.waitForLoadingMainDictionaries( 53 WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS, TimeUnit.MILLISECONDS); 54 return; 55 } catch (final InterruptedException e) { 56 Log.i(TAG, "Interrupted during waiting for loading main dictionary.", e); 57 if (i < MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT - 1) { 58 Log.i(TAG, "Retry", e); 59 } else { 60 Log.w(TAG, "Give up retrying. Retried " 61 + MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT + " times.", e); 62 } 63 } 64 } 65 } 66 resetDictionariesForLocaleLocked()67 private void resetDictionariesForLocaleLocked() { 68 // Nothing to do if the locale is null. This would be the case before any get() calls. 69 if (mLocale != null) { 70 // Note: Given that personalized dictionaries are not used here; we can pass null account. 71 mDictionaryFacilitator.resetDictionaries(mContext, mLocale, 72 mUseContactsDictionary, false /* usePersonalizedDicts */, 73 false /* forceReloadMainDictionary */, null /* account */, 74 mDictionaryNamePrefix, null /* listener */); 75 } 76 } 77 setUseContactsDictionary(final boolean useContactsDictionary)78 public void setUseContactsDictionary(final boolean useContactsDictionary) { 79 synchronized (mLock) { 80 if (mUseContactsDictionary == useContactsDictionary) { 81 // The value has not been changed. 82 return; 83 } 84 mUseContactsDictionary = useContactsDictionary; 85 resetDictionariesForLocaleLocked(); 86 waitForLoadingMainDictionary(mDictionaryFacilitator); 87 } 88 } 89 get(final Locale locale)90 public DictionaryFacilitator get(final Locale locale) { 91 synchronized (mLock) { 92 if (!mDictionaryFacilitator.isForLocale(locale)) { 93 mLocale = locale; 94 resetDictionariesForLocaleLocked(); 95 } 96 waitForLoadingMainDictionary(mDictionaryFacilitator); 97 return mDictionaryFacilitator; 98 } 99 } 100 closeDictionaries()101 public void closeDictionaries() { 102 synchronized (mLock) { 103 mDictionaryFacilitator.closeDictionaries(); 104 } 105 } 106 } 107