Pass a parameter to the dict pack if we don't have a default dict
Also, optimize quite a bit the code that decides whether we have a default dict or not. Bug: 5705834 Change-Id: Ied20fbcbbc42cbe8c01759d11b1804d1156c6960
This commit is contained in:
parent
fed44d08d8
commit
cec8552b18
3 changed files with 42 additions and 51 deletions
|
@ -53,17 +53,23 @@ public class BinaryDictionaryFileDumper {
|
||||||
|
|
||||||
private static final String DICTIONARY_PROJECTION[] = { "id" };
|
private static final String DICTIONARY_PROJECTION[] = { "id" };
|
||||||
|
|
||||||
|
public static final String QUERY_PARAMETER_MAY_PROMPT_USER = "mayPrompt";
|
||||||
|
public static final String QUERY_PARAMETER_TRUE = "true";
|
||||||
|
|
||||||
// Prevents this class to be accidentally instantiated.
|
// Prevents this class to be accidentally instantiated.
|
||||||
private BinaryDictionaryFileDumper() {
|
private BinaryDictionaryFileDumper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return for a given locale or dictionary id the provider URI to get the dictionary.
|
* Returns a URI builder pointing to the dictionary pack.
|
||||||
|
*
|
||||||
|
* This creates a URI builder able to build a URI pointing to the dictionary
|
||||||
|
* pack content provider for a specific dictionary id.
|
||||||
*/
|
*/
|
||||||
private static Uri getProviderUri(String path) {
|
private static Uri.Builder getProviderUriBuilder(final String path) {
|
||||||
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
.authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
|
.authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
|
||||||
path).build();
|
path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,9 +77,13 @@ public class BinaryDictionaryFileDumper {
|
||||||
* available to copy into Latin IME.
|
* available to copy into Latin IME.
|
||||||
*/
|
*/
|
||||||
private static List<WordListInfo> getWordListWordListInfos(final Locale locale,
|
private static List<WordListInfo> getWordListWordListInfos(final Locale locale,
|
||||||
final Context context) {
|
final Context context, final boolean hasDefaultWordList) {
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
final Uri dictionaryPackUri = getProviderUri(locale.toString());
|
final Uri.Builder builder = getProviderUriBuilder(locale.toString());
|
||||||
|
if (!hasDefaultWordList) {
|
||||||
|
builder.appendQueryParameter(QUERY_PARAMETER_MAY_PROMPT_USER, QUERY_PARAMETER_TRUE);
|
||||||
|
}
|
||||||
|
final Uri dictionaryPackUri = builder.build();
|
||||||
|
|
||||||
final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null, null);
|
final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null, null);
|
||||||
if (null == c) return Collections.<WordListInfo>emptyList();
|
if (null == c) return Collections.<WordListInfo>emptyList();
|
||||||
|
@ -132,7 +142,7 @@ public class BinaryDictionaryFileDumper {
|
||||||
final int MODE_MIN = COMPRESSED_CRYPTED_COMPRESSED;
|
final int MODE_MIN = COMPRESSED_CRYPTED_COMPRESSED;
|
||||||
final int MODE_MAX = NONE;
|
final int MODE_MAX = NONE;
|
||||||
|
|
||||||
final Uri wordListUri = getProviderUri(id);
|
final Uri wordListUri = getProviderUriBuilder(id).build();
|
||||||
final String outputFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
|
final String outputFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
|
||||||
|
|
||||||
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
|
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
|
||||||
|
@ -231,9 +241,10 @@ public class BinaryDictionaryFileDumper {
|
||||||
* @throw IOException if the provider-returned data could not be read.
|
* @throw IOException if the provider-returned data could not be read.
|
||||||
*/
|
*/
|
||||||
public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale,
|
public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale,
|
||||||
final Context context) {
|
final Context context, final boolean hasDefaultWordList) {
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
final List<WordListInfo> idList = getWordListWordListInfos(locale, context);
|
final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
|
||||||
|
hasDefaultWordList);
|
||||||
final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
|
final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
|
||||||
for (WordListInfo id : idList) {
|
for (WordListInfo id : idList) {
|
||||||
final AssetFileAddress afd = cacheWordList(id.mId, id.mLocale, resolver, context);
|
final AssetFileAddress afd = cacheWordList(id.mId, id.mLocale, resolver, context);
|
||||||
|
|
|
@ -263,10 +263,12 @@ class BinaryDictionaryGetter {
|
||||||
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
|
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
|
||||||
final Context context) {
|
final Context context) {
|
||||||
|
|
||||||
|
final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale);
|
||||||
// cacheWordListsFromContentProvider returns the list of files it copied to local
|
// cacheWordListsFromContentProvider returns the list of files it copied to local
|
||||||
// storage, but we don't really care about what was copied NOW: what we want is the
|
// storage, but we don't really care about what was copied NOW: what we want is the
|
||||||
// list of everything we ever cached, so we ignore the return value.
|
// list of everything we ever cached, so we ignore the return value.
|
||||||
BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context);
|
BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context,
|
||||||
|
hasDefaultWordList);
|
||||||
final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
|
final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
|
||||||
|
|
||||||
final String mainDictId = getMainDictId(locale);
|
final String mainDictId = getMainDictId(locale);
|
||||||
|
|
|
@ -94,13 +94,14 @@ public class DictionaryFactory {
|
||||||
final Locale locale) {
|
final Locale locale) {
|
||||||
AssetFileDescriptor afd = null;
|
AssetFileDescriptor afd = null;
|
||||||
try {
|
try {
|
||||||
final int resId = getMainDictionaryResourceId(context.getResources(), locale);
|
final int resId =
|
||||||
|
getMainDictionaryResourceIdIfAvailableForLocale(context.getResources(), locale);
|
||||||
|
if (0 == resId) return null;
|
||||||
afd = context.getResources().openRawResourceFd(resId);
|
afd = context.getResources().openRawResourceFd(resId);
|
||||||
if (afd == null) {
|
if (afd == null) {
|
||||||
Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
|
Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!isFullDictionary(afd)) return null;
|
|
||||||
final String sourceDir = context.getApplicationInfo().sourceDir;
|
final String sourceDir = context.getApplicationInfo().sourceDir;
|
||||||
final File packagePath = new File(sourceDir);
|
final File packagePath = new File(sourceDir);
|
||||||
// TODO: Come up with a way to handle a directory.
|
// TODO: Come up with a way to handle a directory.
|
||||||
|
@ -152,55 +153,19 @@ public class DictionaryFactory {
|
||||||
*/
|
*/
|
||||||
public static boolean isDictionaryAvailable(Context context, Locale locale) {
|
public static boolean isDictionaryAvailable(Context context, Locale locale) {
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
final int resourceId = getMainDictionaryResourceId(res, locale);
|
return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
|
||||||
final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
|
|
||||||
final boolean hasDictionary = isFullDictionary(afd);
|
|
||||||
try {
|
|
||||||
if (null != afd) afd.close();
|
|
||||||
} catch (java.io.IOException e) {
|
|
||||||
/* Um, what can we do here exactly? */
|
|
||||||
}
|
|
||||||
return hasDictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Do not use the size of the dictionary as an unique dictionary ID.
|
|
||||||
public static Long getDictionaryId(final Context context, final Locale locale) {
|
|
||||||
final Resources res = context.getResources();
|
|
||||||
final int resourceId = getMainDictionaryResourceId(res, locale);
|
|
||||||
final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
|
|
||||||
final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH)
|
|
||||||
? afd.getLength()
|
|
||||||
: null;
|
|
||||||
try {
|
|
||||||
if (null != afd) afd.close();
|
|
||||||
} catch (java.io.IOException e) {
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Find the Right Way to find out whether the resource is a placeholder or not.
|
|
||||||
// Suggestion : strip the locale, open the placeholder file and store its offset.
|
|
||||||
// Upon opening the file, if it's the same offset, then it's the placeholder.
|
|
||||||
private static final long PLACEHOLDER_LENGTH = 34;
|
|
||||||
/**
|
|
||||||
* Finds out whether the data pointed out by an AssetFileDescriptor is a full
|
|
||||||
* dictionary (as opposed to null, or to a place holder).
|
|
||||||
* @param afd the file descriptor to test, or null
|
|
||||||
* @return true if the dictionary is a real full dictionary, false if it's null or a placeholder
|
|
||||||
*/
|
|
||||||
protected static boolean isFullDictionary(final AssetFileDescriptor afd) {
|
|
||||||
return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String DEFAULT_MAIN_DICT = "main";
|
private static final String DEFAULT_MAIN_DICT = "main";
|
||||||
private static final String MAIN_DICT_PREFIX = "main_";
|
private static final String MAIN_DICT_PREFIX = "main_";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a main dictionary resource id
|
* Helper method to return a dictionary res id for a locale, or 0 if none.
|
||||||
* @param locale dictionary locale
|
* @param locale dictionary locale
|
||||||
* @return main dictionary resource id
|
* @return main dictionary resource id
|
||||||
*/
|
*/
|
||||||
public static int getMainDictionaryResourceId(Resources res, Locale locale) {
|
private static int getMainDictionaryResourceIdIfAvailableForLocale(final Resources res,
|
||||||
|
final Locale locale) {
|
||||||
final String packageName = LatinIME.class.getPackage().getName();
|
final String packageName = LatinIME.class.getPackage().getName();
|
||||||
int resId;
|
int resId;
|
||||||
|
|
||||||
|
@ -218,6 +183,19 @@ public class DictionaryFactory {
|
||||||
return resId;
|
return resId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not found, return 0
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a main dictionary resource id
|
||||||
|
* @param locale dictionary locale
|
||||||
|
* @return main dictionary resource id
|
||||||
|
*/
|
||||||
|
public static int getMainDictionaryResourceId(final Resources res, final Locale locale) {
|
||||||
|
int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
|
||||||
|
if (0 != resourceId) return resourceId;
|
||||||
|
final String packageName = LatinIME.class.getPackage().getName();
|
||||||
return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", packageName);
|
return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue