Change the dictionary file passing schema to a list of ids
The dictionary filename used to be passed directly to Latin IME. This change implements, on the part of Latin IME, the passing of them as an id that should then be passed through openAssetFileDescriptor. Bug: 5095140 Change-Id: I7d1e9d57c19f0645045368f68681680f238189fcmain
parent
c1fd3cf50f
commit
fae8d60ee9
|
@ -20,8 +20,10 @@ import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.AssetFileDescriptor;
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -29,7 +31,8 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -43,6 +46,8 @@ public class BinaryDictionaryFileDumper {
|
||||||
*/
|
*/
|
||||||
static final int FILE_READ_BUFFER_SIZE = 1024;
|
static final int FILE_READ_BUFFER_SIZE = 1024;
|
||||||
|
|
||||||
|
private static final String DICTIONARY_PROJECTION[] = { "id" };
|
||||||
|
|
||||||
// Prevents this class to be accidentally instantiated.
|
// Prevents this class to be accidentally instantiated.
|
||||||
private BinaryDictionaryFileDumper() {
|
private BinaryDictionaryFileDumper() {
|
||||||
}
|
}
|
||||||
|
@ -75,12 +80,47 @@ public class BinaryDictionaryFileDumper {
|
||||||
/**
|
/**
|
||||||
* Return for a given locale the provider URI to query to get the dictionary.
|
* Return for a given locale the provider URI to query to get the dictionary.
|
||||||
*/
|
*/
|
||||||
|
// TODO: remove this
|
||||||
public static Uri getProviderUri(Locale locale) {
|
public static Uri getProviderUri(Locale locale) {
|
||||||
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(
|
||||||
locale.toString()).build();
|
locale.toString()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return for a given locale or dictionary id the provider URI to get the dictionary.
|
||||||
|
*/
|
||||||
|
private static Uri getProviderUri(String path) {
|
||||||
|
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
|
.authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
|
||||||
|
path).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries a content provider for the list of dictionaries for a specific locale
|
||||||
|
* available to copy into Latin IME.
|
||||||
|
*/
|
||||||
|
private static List<String> getDictIdList(final Locale locale, final Context context) {
|
||||||
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
|
final Uri dictionaryPackUri = getProviderUri(locale);
|
||||||
|
|
||||||
|
final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null, null);
|
||||||
|
if (null == c) return Collections.<String>emptyList();
|
||||||
|
if (c.getCount() <= 0 || !c.moveToFirst()) {
|
||||||
|
c.close();
|
||||||
|
return Collections.<String>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
do {
|
||||||
|
final String id = c.getString(0);
|
||||||
|
if (TextUtils.isEmpty(id)) continue;
|
||||||
|
list.add(id);
|
||||||
|
} while (c.moveToNext());
|
||||||
|
c.close();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries a content provider for dictionary data for some locale and returns the file addresses
|
* Queries a content provider for dictionary data for some locale and returns the file addresses
|
||||||
*
|
*
|
||||||
|
@ -95,20 +135,26 @@ public class BinaryDictionaryFileDumper {
|
||||||
* @throw FileNotFoundException if the provider returns non-existent data.
|
* @throw FileNotFoundException if the provider returns non-existent data.
|
||||||
* @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> getDictSetFromContentProvider(Locale locale,
|
public static List<AssetFileAddress> getDictSetFromContentProvider(final Locale locale,
|
||||||
Context context) throws FileNotFoundException, IOException {
|
final Context context) throws FileNotFoundException, IOException {
|
||||||
// TODO: check whether the dictionary is the same or not and if it is, return the cached
|
// TODO: check whether the dictionary is the same or not and if it is, return the cached
|
||||||
// file.
|
// file.
|
||||||
// TODO: This should be able to read a number of files from the dictionary pack, copy
|
// TODO: This should be able to read a number of files from the dictionary pack, copy
|
||||||
// them all and return them.
|
// them all and return them.
|
||||||
final ContentResolver resolver = context.getContentResolver();
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
final Uri dictionaryPackUri = getProviderUri(locale);
|
final List<String> idList = getDictIdList(locale, context);
|
||||||
final AssetFileDescriptor afd = resolver.openAssetFileDescriptor(dictionaryPackUri, "r");
|
final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
|
||||||
if (null == afd) return null;
|
for (String id : idList) {
|
||||||
|
final Uri dictionaryPackUri = getProviderUri(id);
|
||||||
|
final AssetFileDescriptor afd =
|
||||||
|
resolver.openAssetFileDescriptor(dictionaryPackUri, "r");
|
||||||
|
if (null == afd) continue;
|
||||||
final String fileName =
|
final String fileName =
|
||||||
copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context));
|
copyFileTo(afd.createInputStream(), getCacheFileNameForLocale(locale, context));
|
||||||
afd.close();
|
afd.close();
|
||||||
return Arrays.asList(AssetFileAddress.makeFromFileName(fileName));
|
fileAddressList.add(AssetFileAddress.makeFromFileName(fileName));
|
||||||
|
}
|
||||||
|
return fileAddressList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -63,9 +63,6 @@ class BinaryDictionaryGetter {
|
||||||
* Returns a list of file addresses 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 binary dictionaries from various sources, in order:
|
* 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 set, as per the protocol described
|
* - Uses a content provider to get a public dictionary set, as per the protocol described
|
||||||
* in BinaryDictionaryFileDumper.
|
* in BinaryDictionaryFileDumper.
|
||||||
* If that fails:
|
* If that fails:
|
||||||
|
@ -76,14 +73,7 @@ class BinaryDictionaryGetter {
|
||||||
*/
|
*/
|
||||||
public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context,
|
public static List<AssetFileAddress> getDictionaryFiles(Locale locale, Context context,
|
||||||
int fallbackResId) {
|
int fallbackResId) {
|
||||||
// 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 {
|
try {
|
||||||
// If that was no-go, try to find a publicly exported dictionary.
|
|
||||||
List<AssetFileAddress> listFromContentProvider =
|
List<AssetFileAddress> listFromContentProvider =
|
||||||
BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
|
BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
|
||||||
if (null != listFromContentProvider) {
|
if (null != listFromContentProvider) {
|
||||||
|
@ -102,5 +92,4 @@ class BinaryDictionaryGetter {
|
||||||
if (null == fallbackAsset) return null;
|
if (null == fallbackAsset) return null;
|
||||||
return Arrays.asList(fallbackAsset);
|
return Arrays.asList(fallbackAsset);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue