diff options
Diffstat (limited to 'java/src/com/android/inputmethod/dictionarypack/DictionaryService.java')
-rw-r--r-- | java/src/com/android/inputmethod/dictionarypack/DictionaryService.java | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java index 41916b614..bbdf2a380 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java @@ -22,9 +22,12 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; +import android.util.Log; import android.widget.Toast; +import com.android.inputmethod.latin.BinaryDictionaryFileDumper; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.common.LocaleUtils; import java.util.Locale; import java.util.Random; @@ -32,6 +35,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import javax.annotation.Nonnull; + /** * Service that handles background tasks for the dictionary provider. * @@ -50,6 +55,8 @@ import java.util.concurrent.TimeUnit; * to access, and mark the current state as such. */ public final class DictionaryService extends Service { + private static final String TAG = DictionaryService.class.getSimpleName(); + /** * The package name, to use in the intent actions. */ @@ -76,19 +83,29 @@ public final class DictionaryService extends Service { * How often, in milliseconds, we want to update the metadata. This is a * floor value; actually, it may happen several hours later, or even more. */ - private static final long UPDATE_FREQUENCY = TimeUnit.DAYS.toMillis(4); + private static final long UPDATE_FREQUENCY_MILLIS = TimeUnit.DAYS.toMillis(4); /** * We are waked around midnight, local time. We want to wake between midnight and 6 am, * roughly. So use a random time between 0 and this delay. */ - private static final int MAX_ALARM_DELAY = (int)TimeUnit.HOURS.toMillis(6); + private static final int MAX_ALARM_DELAY_MILLIS = (int)TimeUnit.HOURS.toMillis(6); /** * How long we consider a "very long time". If no update took place in this time, * the content provider will trigger an update in the background. */ - private static final long VERY_LONG_TIME = TimeUnit.DAYS.toMillis(14); + private static final long VERY_LONG_TIME_MILLIS = TimeUnit.DAYS.toMillis(14); + + /** + * After starting a download, how long we wait before considering it may be stuck. After this + * period is elapsed, if the keyboard tries to download again, then we cancel and re-register + * the request; if it's within this time, we just leave it be. + * It's important to note that we do not re-submit the request merely because the time is up. + * This is only to decide whether to cancel the old one and re-requesting when the keyboard + * fires a new request for the same data. + */ + public static final long NO_CANCEL_DOWNLOAD_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(30); /** * An executor that serializes tasks given to it. @@ -145,9 +162,14 @@ public final class DictionaryService extends Service { final int startId) { final DictionaryService self = this; if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) { - // This is a UI action, it can't be run in another thread - showStartDownloadingToast(this, LocaleUtils.constructLocaleFromString( - intent.getStringExtra(LOCALE_INTENT_ARGUMENT))); + final String localeString = intent.getStringExtra(LOCALE_INTENT_ARGUMENT); + if (localeString == null) { + Log.e(TAG, "Received " + intent.getAction() + " without locale; skipped"); + } else { + // This is a UI action, it can't be run in another thread + showStartDownloadingToast( + this, LocaleUtils.constructLocaleFromString(localeString)); + } } else { // If it's a command that does not require UI, arrange for the work to be done on a // separate thread, so that we can return right away. The executor will spawn a thread @@ -169,15 +191,28 @@ public final class DictionaryService extends Service { return Service.START_REDELIVER_INTENT; } - private static void dispatchBroadcast(final Context context, final Intent intent) { + static void dispatchBroadcast(final Context context, final Intent intent) { if (DATE_CHANGED_INTENT_ACTION.equals(intent.getAction())) { + // Do not force download dictionaries on date change updates. + CommonPreferences.setForceDownloadDict(context, false); // This happens when the date of the device changes. This normally happens // at midnight local time, but it may happen if the user changes the date // by hand or something similar happens. checkTimeAndMaybeSetupUpdateAlarm(context); } else if (DictionaryPackConstants.UPDATE_NOW_INTENT_ACTION.equals(intent.getAction())) { // Intent to trigger an update now. - UpdateHandler.tryUpdate(context, false); + UpdateHandler.tryUpdate(context, CommonPreferences.isForceDownloadDict(context)); + } else if (DictionaryPackConstants.INIT_AND_UPDATE_NOW_INTENT_ACTION.equals( + intent.getAction())) { + // Enable force download of dictionaries irrespective of wifi or metered connection. + CommonPreferences.setForceDownloadDict(context, true); + + // Initialize the client Db. + final String mClientId = context.getString(R.string.dictionary_pack_client_id); + BinaryDictionaryFileDumper.initializeClientRecordHelper(context, mClientId); + + // Updates the metadata and the download the dictionaries. + UpdateHandler.tryUpdate(context, true); } else { UpdateHandler.downloadFinished(context, intent); } @@ -188,16 +223,16 @@ public final class DictionaryService extends Service { */ private static void checkTimeAndMaybeSetupUpdateAlarm(final Context context) { // Of all clients, if the one that hasn't been updated for the longest - // is still more recent than UPDATE_FREQUENCY, do nothing. - if (!isLastUpdateAtLeastThisOld(context, UPDATE_FREQUENCY)) return; + // is still more recent than UPDATE_FREQUENCY_MILLIS, do nothing. + if (!isLastUpdateAtLeastThisOld(context, UPDATE_FREQUENCY_MILLIS)) return; PrivateLog.log("Date changed - registering alarm"); AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); - // Best effort to wake between midnight and MAX_ALARM_DELAY in the morning. + // Best effort to wake between midnight and MAX_ALARM_DELAY_MILLIS in the morning. // It doesn't matter too much if this is very inexact. final long now = System.currentTimeMillis(); - final long alarmTime = now + new Random().nextInt(MAX_ALARM_DELAY); + final long alarmTime = now + new Random().nextInt(MAX_ALARM_DELAY_MILLIS); final Intent updateIntent = new Intent(DictionaryPackConstants.UPDATE_NOW_INTENT_ACTION); final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, updateIntent, PendingIntent.FLAG_CANCEL_CURRENT); @@ -223,18 +258,19 @@ public final class DictionaryService extends Service { /** * Refreshes data if it hasn't been refreshed in a very long time. * - * This will check the last update time, and if it's been more than VERY_LONG_TIME, + * This will check the last update time, and if it's been more than VERY_LONG_TIME_MILLIS, * update metadata now - and possibly take subsequent update actions. */ public static void updateNowIfNotUpdatedInAVeryLongTime(final Context context) { - if (!isLastUpdateAtLeastThisOld(context, VERY_LONG_TIME)) return; - UpdateHandler.tryUpdate(context, false); + if (!isLastUpdateAtLeastThisOld(context, VERY_LONG_TIME_MILLIS)) return; + UpdateHandler.tryUpdate(context, CommonPreferences.isForceDownloadDict(context)); } /** * Shows a toast informing the user that an automatic dictionary download is starting. */ - private static void showStartDownloadingToast(final Context context, final Locale locale) { + private static void showStartDownloadingToast(final Context context, + @Nonnull final Locale locale) { final String toastText = String.format( context.getString(R.string.toast_downloading_suggestions), locale.getDisplayName()); |