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.latin.personalization; 18 19import java.io.File; 20import java.util.ArrayList; 21import java.util.HashMap; 22import java.util.Locale; 23import java.util.Map; 24import java.util.Random; 25import java.util.concurrent.CountDownLatch; 26import java.util.concurrent.TimeUnit; 27 28import com.android.inputmethod.latin.BinaryDictionary; 29import com.android.inputmethod.latin.Dictionary; 30import com.android.inputmethod.latin.DictionaryFacilitator; 31import com.android.inputmethod.latin.ExpandableBinaryDictionary; 32import com.android.inputmethod.latin.ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback; 33import com.android.inputmethod.latin.makedict.CodePointUtils; 34import com.android.inputmethod.latin.settings.SpacingAndPunctuations; 35 36import android.test.AndroidTestCase; 37import android.test.suitebuilder.annotation.LargeTest; 38import android.util.Log; 39 40/** 41 * Unit tests for personalization dictionary 42 */ 43@LargeTest 44public class PersonalizationDictionaryTests extends AndroidTestCase { 45 private static final String TAG = PersonalizationDictionaryTests.class.getSimpleName(); 46 47 private static final Locale LOCALE_EN_US = new Locale("en", "US"); 48 private static final String DUMMY_PACKAGE_NAME = "test.package.name"; 49 private static final long TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS = 120; 50 51 private DictionaryFacilitator getDictionaryFacilitator() { 52 final ArrayList<String> dictTypes = new ArrayList<>(); 53 dictTypes.add(Dictionary.TYPE_MAIN); 54 dictTypes.add(Dictionary.TYPE_PERSONALIZATION); 55 final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator(); 56 dictionaryFacilitator.resetDictionariesForTesting(getContext(), LOCALE_EN_US, dictTypes, 57 new HashMap<String, File>(), new HashMap<String, Map<String, String>>()); 58 return dictionaryFacilitator; 59 } 60 61 public void testAddManyTokens() { 62 final DictionaryFacilitator dictionaryFacilitator = getDictionaryFacilitator(); 63 dictionaryFacilitator.clearPersonalizationDictionary(); 64 final int dataChunkCount = 20; 65 final int wordCountInOneChunk = 2000; 66 final Random random = new Random(System.currentTimeMillis()); 67 final int[] codePointSet = CodePointUtils.LATIN_ALPHABETS_LOWER; 68 69 final SpacingAndPunctuations spacingAndPunctuations = 70 new SpacingAndPunctuations(getContext().getResources()); 71 72 final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( 73 System.currentTimeMillis()); 74 75 for (int i = 0; i < dataChunkCount; i++) { 76 final ArrayList<String> tokens = new ArrayList<>(); 77 for (int j = 0; j < wordCountInOneChunk; j++) { 78 tokens.add(CodePointUtils.generateWord(random, codePointSet)); 79 } 80 final PersonalizationDataChunk personalizationDataChunk = new PersonalizationDataChunk( 81 true /* inputByUser */, tokens, timeStampInSeconds, DUMMY_PACKAGE_NAME); 82 final CountDownLatch countDownLatch = new CountDownLatch(1); 83 final AddMultipleDictionaryEntriesCallback callback = 84 new AddMultipleDictionaryEntriesCallback() { 85 @Override 86 public void onFinished() { 87 countDownLatch.countDown(); 88 } 89 }; 90 dictionaryFacilitator.addEntriesToPersonalizationDictionary(personalizationDataChunk, 91 spacingAndPunctuations, callback); 92 try { 93 countDownLatch.await(TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS, 94 TimeUnit.SECONDS); 95 } catch (InterruptedException e) { 96 Log.e(TAG, "Interrupted while waiting for finishing dictionary operations.", e); 97 } 98 } 99 dictionaryFacilitator.flushPersonalizationDictionary(); 100 try { 101 dictionaryFacilitator.waitForLoadingDictionariesForTesting( 102 TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS, TimeUnit.SECONDS); 103 } catch (InterruptedException e) { 104 Log.e(TAG, "Interrupted while waiting for finishing dictionary operations.", e); 105 } 106 final String dictName = ExpandableBinaryDictionary.getDictName( 107 PersonalizationDictionary.NAME, LOCALE_EN_US, null /* dictFile */); 108 final File dictFile = ExpandableBinaryDictionary.getDictFile( 109 getContext(), dictName, null /* dictFile */); 110 111 final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 112 0 /* offset */, 0 /* size */, 113 true /* useFullEditDistance */, LOCALE_EN_US, Dictionary.TYPE_PERSONALIZATION, 114 true /* isUpdatable */); 115 assertTrue(binaryDictionary.isValidDictionary()); 116 } 117} 118