Load metadata.json from resources on DB reset.
This will ensure that a new (or upgraded) keyboard instance will know which
dictionaries are available for download so it requests missing dictionaries.
In addition, we increment the database version number to ensure upgrades of
existing Fava instances start with a clean slate.
Bug 22069694.
Change-Id: Id71310412682543a3931f9c5c03cb0369fa7b9ac
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 78d13eb..7d01351 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -50,7 +50,7 @@
private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6;
// The current database version.
// This MUST be increased every time the dictionary pack metadata URL changes.
- private static final int CURRENT_METADATA_DATABASE_VERSION = 15;
+ private static final int CURRENT_METADATA_DATABASE_VERSION = 16;
private final static long NOT_A_DOWNLOAD_ID = -1;
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index d1e3c91..9372572 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -221,7 +221,7 @@
*/
private static void updateClientsWithMetadataUri(
final Context context, final String metadataUri) {
- PrivateLog.log("Update for metadata URI " + DebugLogUtils.s(metadataUri));
+ Log.i(TAG, "updateClientsWithMetadataUri() : MetadataUri = " + metadataUri);
// Adding a disambiguator to circumvent a bug in older versions of DownloadManager.
// DownloadManager also stupidly cuts the extension to replace with its own that it
// gets from the content-type. We need to circumvent this.
@@ -255,7 +255,7 @@
// method will ignore it.
writeMetadataDownloadId(context, metadataUri, downloadId);
}
- PrivateLog.log("Requested download with id " + downloadId);
+ Log.i(TAG, "updateClientsWithMetadataUri() : DownloadId = " + downloadId);
}
/**
@@ -327,11 +327,11 @@
*/
public static long registerDownloadRequest(final DownloadManagerWrapper manager,
final Request request, final SQLiteDatabase db, final String id, final int version) {
- DebugLogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version);
+ Log.i(TAG, "registerDownloadRequest() : Id = " + id + " : Version = " + version);
final long downloadId;
synchronized (sSharedIdProtector) {
downloadId = manager.enqueue(request);
- DebugLogUtils.l("Download requested with id", downloadId);
+ Log.i(TAG, "registerDownloadRequest() : DownloadId = " + downloadId);
MetadataDbHelper.markEntryAsDownloading(db, id, version, downloadId);
}
return downloadId;
@@ -582,7 +582,7 @@
* @throws BadFormatException if the metadata is not in a known format.
* @throws IOException if the downloaded file can't be read from the disk
*/
- private static void handleMetadata(final Context context, final InputStream stream,
+ public static void handleMetadata(final Context context, final InputStream stream,
final String clientId) throws IOException, BadFormatException {
DebugLogUtils.l("Entering handleMetadata");
final List<WordListMetadata> newMetadata;
@@ -905,6 +905,8 @@
// word list ID / client ID combination.
public static void installIfNeverRequested(final Context context, final String clientId,
final String wordlistId, final boolean mayPrompt) {
+ Log.i(TAG, "installIfNeverRequested() : ClientId = " + clientId
+ + " : WordListId = " + wordlistId + " : MayPrompt = " + mayPrompt);
final String[] idArray = wordlistId.split(DictionaryProvider.ID_CATEGORY_SEPARATOR);
// If we have a new-format dictionary id (category:manual_id), then use the
// specified category. Otherwise, it is a main dictionary, so force the
@@ -959,8 +961,8 @@
// change the shared preferences. So there is no way for a word list that has been
// auto-installed once to get auto-installed again, and that's what we want.
final ActionBatch actions = new ActionBatch();
- actions.add(new ActionBatch.StartDownloadAction(
- clientId, WordListMetadata.createFromContentValues(installCandidate)));
+ WordListMetadata metadata = WordListMetadata.createFromContentValues(installCandidate);
+ actions.add(new ActionBatch.StartDownloadAction(clientId, metadata));
final String localeString = installCandidate.getAsString(MetadataDbHelper.LOCALE_COLUMN);
// We are in a content provider: we can't do any UI at all. We have to defer the displaying
// itself to the service. Also, we only display this when the user does not have a
@@ -972,6 +974,7 @@
intent.putExtra(DictionaryService.LOCALE_INTENT_ARGUMENT, localeString);
context.startService(intent);
}
+ Log.i(TAG, "installIfNeverRequested() : StartDownloadAction for " + metadata);
actions.execute(context, new LogProblemReporter(TAG));
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index afedde0..d25c1d3 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -29,6 +29,7 @@
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
import com.android.inputmethod.dictionarypack.MD5Calculator;
+import com.android.inputmethod.dictionarypack.UpdateHandler;
import com.android.inputmethod.latin.common.FileUtils;
import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
@@ -487,6 +488,8 @@
private static void reinitializeClientRecordInDictionaryContentProvider(final Context context,
final ContentProviderClient client, final String clientId) throws RemoteException {
final String metadataFileUri = MetadataFileUriGetter.getMetadataUri(context);
+ Log.i(TAG, "reinitializeClientRecordInDictionaryContentProvider() : MetadataFileUri = "
+ + metadataFileUri);
final String metadataAdditionalId = MetadataFileUriGetter.getMetadataAdditionalId(context);
// Tell the content provider to reset all information about this client id
final Uri metadataContentUri = getProviderUriBuilder(clientId)
@@ -511,9 +514,34 @@
final int length = dictionaryList.size();
for (int i = 0; i < length; ++i) {
final DictionaryInfo info = dictionaryList.get(i);
+ Log.i(TAG, "reinitializeClientRecordInDictionaryContentProvider() : Insert " + info);
client.insert(Uri.withAppendedPath(dictionaryContentUriBase, info.mId),
info.toContentValues());
}
+
+ // Read from metadata file in resources to get the baseline dictionary info.
+ // This ensures we start with a sane list of available dictionaries.
+ final int metadataResourceId = context.getResources().getIdentifier("metadata",
+ "raw", DictionaryInfoUtils.RESOURCE_PACKAGE_NAME);
+ if (metadataResourceId == 0) {
+ Log.w(TAG, "Missing metadata.json resource");
+ return;
+ }
+ InputStream inputStream = null;
+ try {
+ inputStream = context.getResources().openRawResource(metadataResourceId);
+ UpdateHandler.handleMetadata(context, inputStream, clientId);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to read metadata.json from resources", e);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to close metadata.json", e);
+ }
+ }
+ }
}
/**
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index 096a545..11cccd5 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -54,7 +54,7 @@
*/
public class DictionaryInfoUtils {
private static final String TAG = DictionaryInfoUtils.class.getSimpleName();
- private static final String RESOURCE_PACKAGE_NAME = R.class.getPackage().getName();
+ public static final String RESOURCE_PACKAGE_NAME = R.class.getPackage().getName();
private static final String DEFAULT_MAIN_DICT = "main";
private static final String MAIN_DICT_PREFIX = "main_";
private static final String DECODER_DICT_SUFFIX = DecoderSpecificConstants.DECODER_DICT_SUFFIX;
@@ -103,6 +103,13 @@
values.put(VERSION_COLUMN, mVersion);
return values;
}
+
+ @Override
+ public String toString() {
+ return "DictionaryInfo : Id = '" + mId
+ + "' : Locale=" + mLocale
+ + " : Version=" + mVersion;
+ }
}
private DictionaryInfoUtils() {