aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/dictionarypack/DictionaryService.java')
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryService.java50
1 files changed, 36 insertions, 14 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
index 41916b614..c678f081d 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
@@ -22,9 +22,11 @@ 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.R;
+import com.android.inputmethod.latin.common.LocaleUtils;
import java.util.Locale;
import java.util.Random;
@@ -32,6 +34,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 +54,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 +82,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 +161,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,7 +190,7 @@ 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())) {
// 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
@@ -188,16 +209,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 +244,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;
+ if (!isLastUpdateAtLeastThisOld(context, VERY_LONG_TIME_MILLIS)) return;
UpdateHandler.tryUpdate(context, false);
}
/**
* 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());