diff options
Diffstat (limited to 'java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java')
-rw-r--r-- | java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java | 127 |
1 files changed, 79 insertions, 48 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java index 6fbca44c5..90a750493 100644 --- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java @@ -31,7 +31,6 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.ConnectivityManager; import android.net.Uri; -import android.os.Build; import android.os.ParcelFileDescriptor; import android.text.TextUtils; import android.util.Log; @@ -252,12 +251,16 @@ public final class UpdateHandler { res.getBoolean(R.bool.metadata_downloads_visible_in_download_UI)); final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); - cancelUpdateWithDownloadManager(context, metadataUri, manager); + if (maybeCancelUpdateAndReturnIfStillRunning(context, metadataUri, manager, + DictionaryService.NO_CANCEL_DOWNLOAD_PERIOD_MILLIS)) { + // We already have a recent download in progress. Don't register a new download. + return; + } final long downloadId; synchronized (sSharedIdProtector) { downloadId = manager.enqueue(metadataRequest); DebugLogUtils.l("Metadata download requested with id", downloadId); - // If there is already a download in progress, it's been there for a while and + // If there is still a download in progress, it's been there for a while and // there is probably something wrong with download manager. It's best to just // overwrite the id and request it again. If the old one happens to finish // anyway, we don't know about its ID any more, so the downloadFinished @@ -268,21 +271,29 @@ public final class UpdateHandler { } /** - * Cancels downloading a file, if there is one for this URI. + * Cancels downloading a file if there is one for this URI and it's too long. * * If we are not currently downloading the file at this URI, this is a no-op. * * @param context the context to open the database on * @param metadataUri the URI to cancel * @param manager an wrapped instance of DownloadManager + * @param graceTime if there was a download started less than this many milliseconds, don't + * cancel and return true + * @return whether the download is still active */ - private static void cancelUpdateWithDownloadManager(final Context context, - final String metadataUri, final DownloadManagerWrapper manager) { + private static boolean maybeCancelUpdateAndReturnIfStillRunning(final Context context, + final String metadataUri, final DownloadManagerWrapper manager, final long graceTime) { synchronized (sSharedIdProtector) { - final long metadataDownloadId = - MetadataDbHelper.getMetadataDownloadIdForURI(context, metadataUri); - if (NOT_AN_ID == metadataDownloadId) return; - manager.remove(metadataDownloadId); + final DownloadIdAndStartDate metadataDownloadIdAndStartDate = + MetadataDbHelper.getMetadataDownloadIdAndStartDateForURI(context, metadataUri); + if (null == metadataDownloadIdAndStartDate) return false; + if (NOT_AN_ID == metadataDownloadIdAndStartDate.mId) return false; + if (metadataDownloadIdAndStartDate.mStartDate + graceTime + > System.currentTimeMillis()) { + return true; + } + manager.remove(metadataDownloadIdAndStartDate.mId); writeMetadataDownloadId(context, metadataUri, NOT_AN_ID); } // Consider a cancellation as a failure. As such, inform listeners that the download @@ -290,6 +301,7 @@ public final class UpdateHandler { for (UpdateEventListener listener : linkedCopyOfList(sUpdateEventListeners)) { listener.downloadedMetadata(false); } + return false; } /** @@ -304,7 +316,7 @@ public final class UpdateHandler { public static void cancelUpdate(final Context context, final String clientId) { final DownloadManagerWrapper manager = new DownloadManagerWrapper(context); final String metadataUri = MetadataDbHelper.getMetadataUriAsString(context, clientId); - cancelUpdateWithDownloadManager(context, metadataUri, manager); + maybeCancelUpdateAndReturnIfStillRunning(context, metadataUri, manager, 0 /* graceTime */); } /** @@ -388,7 +400,7 @@ public final class UpdateHandler { // If any of these is metadata, we should update the DB boolean hasMetadata = false; for (DownloadRecord record : downloadRecords) { - if (null == record.mAttributes) { + if (record.isMetadata()) { hasMetadata = true; break; } @@ -785,6 +797,10 @@ public final class UpdateHandler { } else { final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId); if (newInfo.mVersion == currentInfo.mVersion) { + if (newInfo.mRemoteFilename == currentInfo.mRemoteFilename) { + // If the dictionary url hasn't changed, we should preserve the retryCount. + newInfo.mRetryCount = currentInfo.mRetryCount; + } // If it's the same id/version, we update the DB with the new values. // It doesn't matter too much if they didn't change. actions.add(new ActionBatch.UpdateDataAction(clientId, newInfo)); @@ -987,16 +1003,17 @@ public final class UpdateHandler { public static void markAsUsed(final Context context, final String clientId, final String wordlistId, final int version, final int status, final boolean allowDownloadOnMeteredData) { - final List<WordListMetadata> currentMetadata = - MetadataHandler.getCurrentMetadata(context, clientId); - WordListMetadata wordList = MetadataHandler.findWordListById(currentMetadata, wordlistId); - if (null == wordList) return; + final WordListMetadata wordListMetaData = MetadataHandler.getCurrentMetadataForWordList( + context, clientId, wordlistId, version); + + if (null == wordListMetaData) return; + final ActionBatch actions = new ActionBatch(); if (MetadataDbHelper.STATUS_DISABLED == status || MetadataDbHelper.STATUS_DELETING == status) { - actions.add(new ActionBatch.EnableAction(clientId, wordList)); + actions.add(new ActionBatch.EnableAction(clientId, wordListMetaData)); } else if (MetadataDbHelper.STATUS_AVAILABLE == status) { - actions.add(new ActionBatch.StartDownloadAction(clientId, wordList, + actions.add(new ActionBatch.StartDownloadAction(clientId, wordListMetaData, allowDownloadOnMeteredData)); } else { Log.e(TAG, "Unexpected state of the word list for markAsUsed : " + status); @@ -1022,13 +1039,13 @@ public final class UpdateHandler { // markAsUsed for consistency. public static void markAsUnused(final Context context, final String clientId, final String wordlistId, final int version, final int status) { - final List<WordListMetadata> currentMetadata = - MetadataHandler.getCurrentMetadata(context, clientId); - final WordListMetadata wordList = - MetadataHandler.findWordListById(currentMetadata, wordlistId); - if (null == wordList) return; + + final WordListMetadata wordListMetaData = MetadataHandler.getCurrentMetadataForWordList( + context, clientId, wordlistId, version); + + if (null == wordListMetaData) return; final ActionBatch actions = new ActionBatch(); - actions.add(new ActionBatch.DisableAction(clientId, wordList)); + actions.add(new ActionBatch.DisableAction(clientId, wordListMetaData)); actions.execute(context, new LogProblemReporter(TAG)); signalNewDictionaryState(context); } @@ -1051,14 +1068,14 @@ public final class UpdateHandler { */ public static void markAsDeleting(final Context context, final String clientId, final String wordlistId, final int version, final int status) { - final List<WordListMetadata> currentMetadata = - MetadataHandler.getCurrentMetadata(context, clientId); - final WordListMetadata wordList = - MetadataHandler.findWordListById(currentMetadata, wordlistId); - if (null == wordList) return; + + final WordListMetadata wordListMetaData = MetadataHandler.getCurrentMetadataForWordList( + context, clientId, wordlistId, version); + + if (null == wordListMetaData) return; final ActionBatch actions = new ActionBatch(); - actions.add(new ActionBatch.DisableAction(clientId, wordList)); - actions.add(new ActionBatch.StartDeleteAction(clientId, wordList)); + actions.add(new ActionBatch.DisableAction(clientId, wordListMetaData)); + actions.add(new ActionBatch.StartDeleteAction(clientId, wordListMetaData)); actions.execute(context, new LogProblemReporter(TAG)); signalNewDictionaryState(context); } @@ -1076,33 +1093,47 @@ public final class UpdateHandler { */ public static void markAsDeleted(final Context context, final String clientId, final String wordlistId, final int version, final int status) { - final List<WordListMetadata> currentMetadata = - MetadataHandler.getCurrentMetadata(context, clientId); - final WordListMetadata wordList = - MetadataHandler.findWordListById(currentMetadata, wordlistId); - if (null == wordList) return; + final WordListMetadata wordListMetaData = MetadataHandler.getCurrentMetadataForWordList( + context, clientId, wordlistId, version); + + if (null == wordListMetaData) return; + final ActionBatch actions = new ActionBatch(); - actions.add(new ActionBatch.FinishDeleteAction(clientId, wordList)); + actions.add(new ActionBatch.FinishDeleteAction(clientId, wordListMetaData)); actions.execute(context, new LogProblemReporter(TAG)); signalNewDictionaryState(context); } /** - * Marks the word list with the passed id as broken. - * - * This effectively deletes the entry from the metadata. It doesn't prevent the same - * word list to be downloaded again at a later time if the same or a new version is - * available the next time we download the metadata. + * Checks whether the word list should be downloaded again; in which case an download & + * installation attempt is made. Otherwise the word list is marked broken. * * @param context the context to open the database on. * @param clientId the id of the client. - * @param wordlistId the id of the word list to mark as broken. - * @param version the version of the word list to mark as deleted. + * @param wordlistId the id of the word list which is broken. + * @param version the version of the broken word list. */ - public static void markAsBroken(final Context context, final String clientId, + public static void markAsBrokenOrRetrying(final Context context, final String clientId, final String wordlistId, final int version) { - // TODO: do this on another thread to avoid blocking the UI. - MetadataDbHelper.deleteEntry(MetadataDbHelper.getDb(context, clientId), - wordlistId, version); + boolean isRetryPossible = MetadataDbHelper.maybeMarkEntryAsRetrying( + MetadataDbHelper.getDb(context, clientId), wordlistId, version); + + if (isRetryPossible) { + if (DEBUG) { + Log.d(TAG, "Attempting to download & install the wordlist again."); + } + final WordListMetadata wordListMetaData = MetadataHandler.getCurrentMetadataForWordList( + context, clientId, wordlistId, version); + + final ActionBatch actions = new ActionBatch(); + actions.add(new ActionBatch.StartDownloadAction(clientId, wordListMetaData, false)); + actions.execute(context, new LogProblemReporter(TAG)); + } else { + if (DEBUG) { + Log.d(TAG, "Retries for wordlist exhausted, deleting the wordlist from table."); + } + MetadataDbHelper.deleteEntry(MetadataDbHelper.getDb(context, clientId), + wordlistId, version); + } } } |