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
This commit is contained in:
Dan Zivkovic 2015-06-24 17:40:52 -07:00
parent c32389ce11
commit 3aad142435
4 changed files with 47 additions and 9 deletions

View file

@ -50,7 +50,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
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;

View file

@ -221,7 +221,7 @@ public final class UpdateHandler {
*/
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 @@ public final class UpdateHandler {
// 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 final class UpdateHandler {
*/
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 @@ public final class UpdateHandler {
* @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 @@ public final class UpdateHandler {
// 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 @@ public final class UpdateHandler {
// 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 @@ public final class UpdateHandler {
intent.putExtra(DictionaryService.LOCALE_INTENT_ARGUMENT, localeString);
context.startService(intent);
}
Log.i(TAG, "installIfNeverRequested() : StartDownloadAction for " + metadata);
actions.execute(context, new LogProblemReporter(TAG));
}

View file

@ -29,6 +29,7 @@ import android.util.Log;
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 @@ public final class BinaryDictionaryFileDumper {
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 @@ public final class BinaryDictionaryFileDumper {
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);
}
}
}
}
/**

View file

@ -54,7 +54,7 @@ import javax.annotation.Nullable;
*/
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 @@ public class DictionaryInfoUtils {
values.put(VERSION_COLUMN, mVersion);
return values;
}
@Override
public String toString() {
return "DictionaryInfo : Id = '" + mId
+ "' : Locale=" + mLocale
+ " : Version=" + mVersion;
}
}
private DictionaryInfoUtils() {