am d4cbc4fd: Implement getting data files with protocol v2

* commit 'd4cbc4fd078cbb23be4eafe1cb82a8a470fca3a0':
  Implement getting data files with protocol v2
main
Jean Chalard 2013-02-15 19:41:27 -08:00 committed by Android Git Automerger
commit a2f89c525d
1 changed files with 56 additions and 27 deletions

View File

@ -74,6 +74,8 @@ public final class BinaryDictionaryFileDumper {
// The path fragment to append after the client ID for dictionary info requests. // The path fragment to append after the client ID for dictionary info requests.
private static final String QUERY_PATH_DICT_INFO = "dict"; private static final String QUERY_PATH_DICT_INFO = "dict";
// The path fragment to append after the client ID for dictionary datafile requests.
private static final String QUERY_PATH_DATAFILE = "datafile";
// The path fragment to append after the client ID for updating the metadata URI. // The path fragment to append after the client ID for updating the metadata URI.
private static final String QUERY_PATH_METADATA = "metadata"; private static final String QUERY_PATH_METADATA = "metadata";
private static final String INSERT_METADATA_CLIENT_ID_COLUMN = "clientid"; private static final String INSERT_METADATA_CLIENT_ID_COLUMN = "clientid";
@ -156,7 +158,7 @@ public final class BinaryDictionaryFileDumper {
c.close(); c.close();
return Collections.<WordListInfo>emptyList(); return Collections.<WordListInfo>emptyList();
} }
final List<WordListInfo> list = CollectionUtils.newArrayList(); final ArrayList<WordListInfo> list = CollectionUtils.newArrayList();
do { do {
final String wordListId = c.getString(0); final String wordListId = c.getString(0);
final String wordListLocale = c.getString(1); final String wordListLocale = c.getString(1);
@ -186,13 +188,18 @@ public final class BinaryDictionaryFileDumper {
/** /**
* Helper method to encapsulate exception handling. * Helper method to encapsulate exception handling.
*/ */
private static AssetFileDescriptor openAssetFileDescriptor(final ContentResolver resolver, private static AssetFileDescriptor openAssetFileDescriptor(
final Uri uri) { final ContentProviderClient providerClient, final Uri uri) {
try { try {
return resolver.openAssetFileDescriptor(uri, "r"); return providerClient.openAssetFile(uri, "r");
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
// I don't want to log the word list URI here for security concerns // I don't want to log the word list URI here for security concerns. The exception
Log.e(TAG, "Could not find a word list from the dictionary provider."); // contains the name of the file, so let's not pass it to Log.e here.
Log.e(TAG, "Could not find a word list from the dictionary provider."
/* intentionally don't pass the exception (see comment above) */);
return null;
} catch (RemoteException e) {
Log.e(TAG, "Can't communicate with the dictionary pack", e);
return null; return null;
} }
} }
@ -202,9 +209,8 @@ public final class BinaryDictionaryFileDumper {
* to the cache file name designated by its id and locale, overwriting it if already present * to the cache file name designated by its id and locale, overwriting it if already present
* and creating it (and its containing directory) if necessary. * and creating it (and its containing directory) if necessary.
*/ */
private static AssetFileAddress cacheWordList(final String id, final String locale, private static AssetFileAddress cacheWordList(final String wordlistId, final String locale,
final ContentResolver resolver, final Context context) { final ContentProviderClient providerClient, final Context context) {
final int COMPRESSED_CRYPTED_COMPRESSED = 0; final int COMPRESSED_CRYPTED_COMPRESSED = 0;
final int CRYPTED_COMPRESSED = 1; final int CRYPTED_COMPRESSED = 1;
final int COMPRESSED_CRYPTED = 2; final int COMPRESSED_CRYPTED = 2;
@ -214,11 +220,20 @@ public final 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.Builder wordListUriBuilder = getProviderUriBuilder(id); final String clientId = context.getString(R.string.dictionary_pack_client_id);
final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context); final Uri.Builder wordListUriBuilder;
try {
wordListUriBuilder = getContentUriBuilderForType(clientId,
providerClient, QUERY_PATH_DATAFILE, wordlistId /* extraPath */);
} catch (RemoteException e) {
Log.e(TAG, "Can't communicate with the dictionary pack", e);
return null;
}
final String finalFileName =
DictionaryInfoUtils.getCacheFileName(wordlistId, locale, context);
String tempFileName; String tempFileName;
try { try {
tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); tempFileName = BinaryDictionaryGetter.getTempFileName(wordlistId, context);
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Can't open the temporary file", e); Log.e(TAG, "Can't open the temporary file", e);
return null; return null;
@ -236,7 +251,7 @@ public final class BinaryDictionaryFileDumper {
final Uri wordListUri = wordListUriBuilder.build(); final Uri wordListUri = wordListUriBuilder.build();
try { try {
// Open input. // Open input.
afd = openAssetFileDescriptor(resolver, wordListUri); afd = openAssetFileDescriptor(providerClient, wordListUri);
// If we can't open it at all, don't even try a number of times. // If we can't open it at all, don't even try a number of times.
if (null == afd) return null; if (null == afd) return null;
originalSourceStream = afd.createInputStream(); originalSourceStream = afd.createInputStream();
@ -284,10 +299,10 @@ public final class BinaryDictionaryFileDumper {
} }
wordListUriBuilder.appendQueryParameter(QUERY_PARAMETER_DELETE_RESULT, wordListUriBuilder.appendQueryParameter(QUERY_PARAMETER_DELETE_RESULT,
QUERY_PARAMETER_SUCCESS); QUERY_PARAMETER_SUCCESS);
if (0 >= resolver.delete(wordListUriBuilder.build(), null, null)) { if (0 >= providerClient.delete(wordListUriBuilder.build(), null, null)) {
Log.e(TAG, "Could not have the dictionary pack delete a word list"); Log.e(TAG, "Could not have the dictionary pack delete a word list");
} }
BinaryDictionaryGetter.removeFilesWithIdExcept(context, id, finalFile); BinaryDictionaryGetter.removeFilesWithIdExcept(context, wordlistId, finalFile);
// Success! Close files (through the finally{} clause) and return. // Success! Close files (through the finally{} clause) and return.
return AssetFileAddress.makeFromFileName(finalFileName); return AssetFileAddress.makeFromFileName(finalFileName);
} catch (Exception e) { } catch (Exception e) {
@ -327,9 +342,13 @@ public final class BinaryDictionaryFileDumper {
// as invalid. // as invalid.
wordListUriBuilder.appendQueryParameter(QUERY_PARAMETER_DELETE_RESULT, wordListUriBuilder.appendQueryParameter(QUERY_PARAMETER_DELETE_RESULT,
QUERY_PARAMETER_FAILURE); QUERY_PARAMETER_FAILURE);
if (0 >= resolver.delete(wordListUriBuilder.build(), null, null)) { try {
if (0 >= providerClient.delete(wordListUriBuilder.build(), null, null)) {
Log.e(TAG, "In addition, we were unable to delete it."); Log.e(TAG, "In addition, we were unable to delete it.");
} }
} catch (RemoteException e) {
Log.e(TAG, "In addition, communication with the dictionary provider was cut", e);
}
return null; return null;
} }
@ -345,17 +364,27 @@ public final class BinaryDictionaryFileDumper {
*/ */
public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale, public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale,
final Context context, final boolean hasDefaultWordList) { final Context context, final boolean hasDefaultWordList) {
final ContentResolver resolver = context.getContentResolver(); final ContentProviderClient providerClient = context.getContentResolver().
acquireContentProviderClient(getProviderUriBuilder("").build());
if (null == providerClient) {
Log.e(TAG, "Can't establish communication with the dictionary provider");
return CollectionUtils.newArrayList();
}
try {
final List<WordListInfo> idList = getWordListWordListInfos(locale, context, final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
hasDefaultWordList); hasDefaultWordList);
final List<AssetFileAddress> fileAddressList = CollectionUtils.newArrayList(); final ArrayList<AssetFileAddress> fileAddressList = CollectionUtils.newArrayList();
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, providerClient, context);
if (null != afd) { if (null != afd) {
fileAddressList.add(afd); fileAddressList.add(afd);
} }
} }
return fileAddressList; return fileAddressList;
} finally {
providerClient.release();
}
} }
/** /**