From d8f52a4f18d22aa150846b01017410ce70bbad6f Mon Sep 17 00:00:00 2001 From: Jean Chalard <jchalard@google.com> Date: Wed, 27 Apr 2011 23:13:11 +0900 Subject: [PATCH] Improve the architecture to support multiple dictionaries. This change enables the interface to get multiple dictionaries from a dictionary pack. It only implements it to the end in the case of the proprietary method, as the open method needs still some working out, and the "inside the package" method does not need it. This change goes together with Iaa95bf36, and breaks the build without it. Bug: 1752028 Change-Id: I3ccfd696e8ef083ef9c074e1c3e4bb0bf2fcfd23 --- .../latin/BinaryDictionaryFileDumper.java | 21 ++++++++----- .../latin/BinaryDictionaryGetter.java | 30 +++++++++---------- .../latin/DictionaryCollection.java | 5 ++++ .../inputmethod/latin/DictionaryFactory.java | 17 ++++++----- .../latin/PrivateBinaryDictionaryGetter.java | 3 +- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index a78ff7e84b..76a230f822 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -28,6 +28,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.List; import java.util.Locale; /** @@ -79,27 +81,32 @@ public class BinaryDictionaryFileDumper { } /** - * Queries a content provider for dictionary data for some locale and returns it as a file name. + * Queries a content provider for dictionary data for some locale and returns the file addresses * * This will query a content provider for dictionary data for a given locale, and return - * the name of a file suitable to be mmap'ed. It will copy it to local storage if needed. - * It should also check the dictionary version to avoid unnecessary copies but this is + * the addresses of a file set the members of which are suitable to be mmap'ed. It will copy + * them to local storage if needed. + * It should also check the dictionary versions to avoid unnecessary copies but this is * still in TODO state. * This will make the data from the content provider the cached dictionary for this locale, * overwriting any previous cached data. - * @returns the name of the file, or null if no data could be obtained. + * @returns the addresses of the files, or null if no data could be obtained. * @throw FileNotFoundException if the provider returns non-existent data. * @throw IOException if the provider-returned data could not be read. */ - public static String getDictionaryFileFromContentProvider(Locale locale, Context context) - throws FileNotFoundException, IOException { + public static List<AssetFileAddress> getDictSetFromContentProvider(Locale locale, + Context context) throws FileNotFoundException, IOException { // TODO: check whether the dictionary is the same or not and if it is, return the cached // file. + // TODO: This should be able to read a number of files from the dictionary pack, copy + // them all and return them. final ContentResolver resolver = context.getContentResolver(); final Uri dictionaryPackUri = getProviderUri(locale); final AssetFileDescriptor afd = resolver.openAssetFileDescriptor(dictionaryPackUri, "r"); if (null == afd) return null; - return copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context)); + final String fileName = + copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context)); + return Arrays.asList(AssetFileAddress.makeFromFileName(fileName)); } /** diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index c4e098a0cb..562580d413 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -22,6 +22,8 @@ import android.util.Log; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Arrays; +import java.util.List; import java.util.Locale; /** @@ -52,13 +54,13 @@ class BinaryDictionaryGetter { } /** - * Returns a file address for a given locale, trying relevant methods in order. + * Returns a list of file addresses for a given locale, trying relevant methods in order. * - * Tries to get a binary dictionary from various sources, in order: - * - Uses a private method of getting a private dictionary, as implemented by the + * Tries to get binary dictionaries from various sources, in order: + * - Uses a private method of getting a private dictionaries, as implemented by the * PrivateBinaryDictionaryGetter class. * If that fails: - * - Uses a content provider to get a public dictionary, as per the protocol described + * - Uses a content provider to get a public dictionary set, as per the protocol described * in BinaryDictionaryFileDumper. * If that fails: * - Gets a file name from the fallback resource passed as an argument. @@ -66,27 +68,25 @@ class BinaryDictionaryGetter { * - Returns null. * @return The address of a valid file, or null. */ - public static AssetFileAddress getDictionaryFile(Locale locale, Context context, + public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context, int fallbackResId) { - // Try first to query a private file signed the same way. - final AssetFileAddress privateFile = - PrivateBinaryDictionaryGetter.getDictionaryFile(locale, context); - if (null != privateFile) { - return privateFile; + // Try first to query a private package signed the same way for private files. + final List<AssetFileAddress> privateFiles = + PrivateBinaryDictionaryGetter.getDictionaryFiles(locale, context); + if (null != privateFiles) { + return privateFiles; } else { try { // If that was no-go, try to find a publicly exported dictionary. - final String fileName = BinaryDictionaryFileDumper. - getDictionaryFileFromContentProvider(locale, context); - return AssetFileAddress.makeFromFileName(fileName); + return BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context); } catch (FileNotFoundException e) { Log.e(TAG, "Unable to create dictionary file from provider for locale " + locale.toString() + ": falling back to internal dictionary"); - return loadFallbackResource(context, fallbackResId); + return Arrays.asList(loadFallbackResource(context, fallbackResId)); } catch (IOException e) { Log.e(TAG, "Unable to read source data for locale " + locale.toString() + ": falling back to internal dictionary"); - return loadFallbackResource(context, fallbackResId); + return Arrays.asList(loadFallbackResource(context, fallbackResId)); } } } diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index 4b64e5344a..3fcb6ed557 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -34,6 +35,10 @@ public class DictionaryCollection extends Dictionary { mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); } + public DictionaryCollection(Collection<Dictionary> dictionaries) { + mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); + } + @Override public void getWords(final WordComposer composer, final WordCallback callback) { for (final Dictionary dict : mDictionaries) diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 2dbd582f35..605676d703 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -18,11 +18,12 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.res.AssetFileDescriptor; -import android.content.res.Configuration; import android.content.res.Resources; import android.util.Log; import java.io.File; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; /** @@ -50,11 +51,14 @@ public class DictionaryFactory { return new DictionaryCollection(createBinaryDictionary(context, fallbackResId)); } - final AssetFileAddress dictFile = BinaryDictionaryGetter.getDictionaryFile(locale, - context, fallbackResId); - if (null == dictFile) return null; - return new DictionaryCollection(new BinaryDictionary(context, - dictFile.mFilename, dictFile.mOffset, dictFile.mLength, null)); + final List<Dictionary> dictList = new LinkedList<Dictionary>(); + for (final AssetFileAddress f : BinaryDictionaryGetter.getDictionaryFiles(locale, + context, fallbackResId)) { + dictList.add(new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength, null)); + } + + if (null == dictList) return null; + return new DictionaryCollection(dictList); } /** @@ -66,7 +70,6 @@ public class DictionaryFactory { protected static BinaryDictionary createBinaryDictionary(Context context, int resId) { AssetFileDescriptor afd = null; try { - // TODO: IMPORTANT: Do not create a dictionary from a placeholder. afd = context.getResources().openRawResourceFd(resId); if (afd == null) { Log.e(TAG, "Found the resource but it is compressed. resId=" + resId); diff --git a/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java index 90726b0d8e..eb740e111c 100644 --- a/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/PrivateBinaryDictionaryGetter.java @@ -18,11 +18,12 @@ package com.android.inputmethod.latin; import android.content.Context; +import java.util.List; import java.util.Locale; class PrivateBinaryDictionaryGetter { private PrivateBinaryDictionaryGetter() {} - public static AssetFileAddress getDictionaryFile(Locale locale, Context context) { + public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context) { return null; } } -- GitLab