Force download the dictionaries after the apk package is updated.
- Also display the notification when the dictionaries are auto updated Bug: 19808828 Change-Id: If5c4efb73d8bb554d812afcf7deafec3ac40a462main
parent
e1b91d4138
commit
3bc3bc7971
|
@ -62,4 +62,11 @@ public class DictionaryPackConstants {
|
|||
*/
|
||||
public static final String UPDATE_NOW_INTENT_ACTION = DICTIONARY_DOMAIN
|
||||
+ ".UPDATE_NOW";
|
||||
|
||||
/**
|
||||
* The intent action to inform the dictionary provider to initialize the db
|
||||
* and update now.
|
||||
*/
|
||||
public static final String INIT_AND_UPDATE_NOW_INTENT_ACTION = DICTIONARY_DOMAIN
|
||||
+ ".INIT_AND_UPDATE_NOW";
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@
|
|||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
<action android:name="android.intent.action.DATE_CHANGED" />
|
||||
<action android:name="com.android.inputmethod.dictionarypack.aosp.UPDATE_NOW" />
|
||||
<action android:name="com.android.inputmethod.dictionarypack.aosp.INIT_AND_UPDATE_NOW" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
|
|
|
@ -25,6 +25,6 @@
|
|||
<bool name="allow_over_roaming">false</bool>
|
||||
<bool name="dict_downloads_visible_in_download_UI">false</bool>
|
||||
<bool name="metadata_downloads_visible_in_download_UI">false</bool>
|
||||
<bool name="display_notification_for_auto_update">false</bool>
|
||||
<bool name="display_notification_for_user_requested_update">false</bool>
|
||||
<bool name="display_notification_for_auto_update">true</bool>
|
||||
<bool name="display_notification_for_user_requested_update">true</bool>
|
||||
</resources>
|
||||
|
|
|
@ -173,7 +173,7 @@ public final class ActionBatch {
|
|||
final long downloadId = UpdateHandler.registerDownloadRequest(manager, request, db,
|
||||
mWordList.mId, mWordList.mVersion);
|
||||
Log.i(TAG, String.format("Starting the dictionary download with version:"
|
||||
+ " %d and Url: %s" + mWordList.mVersion, uri));
|
||||
+ " %d and Url: %s", mWordList.mVersion, uri));
|
||||
DebugLogUtils.l("Starting download of", uri, "with id", downloadId);
|
||||
PrivateLog.log("Starting download of " + uri + ", id : " + downloadId);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import android.content.SharedPreferences;
|
|||
public final class CommonPreferences {
|
||||
private static final String COMMON_PREFERENCES_NAME = "LatinImeDictPrefs";
|
||||
|
||||
public static final String PREF_FORCE_DOWNLOAD_DICT = "pref_key_force_download_dict";
|
||||
|
||||
public static SharedPreferences getCommonPreferences(final Context context) {
|
||||
return context.getSharedPreferences(COMMON_PREFERENCES_NAME, 0);
|
||||
}
|
||||
|
@ -37,4 +39,14 @@ public final class CommonPreferences {
|
|||
editor.putBoolean(id, false);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static boolean isForceDownloadDict(Context context) {
|
||||
return getCommonPreferences(context).getBoolean(PREF_FORCE_DOWNLOAD_DICT, false);
|
||||
}
|
||||
|
||||
public static void setForceDownloadDict(Context context, boolean forceDownload) {
|
||||
SharedPreferences.Editor editor = getCommonPreferences(context).edit();
|
||||
editor.putBoolean(PREF_FORCE_DOWNLOAD_DICT, forceDownload);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ 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;
|
||||
|
||||
|
@ -192,13 +193,26 @@ public final class DictionaryService extends Service {
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -249,7 +263,7 @@ public final class DictionaryService extends Service {
|
|||
*/
|
||||
public static void updateNowIfNotUpdatedInAVeryLongTime(final Context context) {
|
||||
if (!isLastUpdateAtLeastThisOld(context, VERY_LONG_TIME_MILLIS)) return;
|
||||
UpdateHandler.tryUpdate(context, false);
|
||||
UpdateHandler.tryUpdate(context, CommonPreferences.isForceDownloadDict(context));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -264,6 +264,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
|
|||
*/
|
||||
@Override
|
||||
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||
// Allow automatic download of dictionaries on upgrading the database.
|
||||
CommonPreferences.setForceDownloadDict(mContext, true);
|
||||
if (METADATA_DATABASE_INITIAL_VERSION == oldVersion
|
||||
&& METADATA_DATABASE_VERSION_WITH_CLIENTID <= newVersion
|
||||
&& CURRENT_METADATA_DATABASE_VERSION >= newVersion) {
|
||||
|
|
|
@ -449,6 +449,8 @@ public final class UpdateHandler {
|
|||
// download, so we are pretty sure it's alive. It's theoretically possible that it's
|
||||
// disabled right inbetween the firing of the intent and the control reaching here.
|
||||
|
||||
boolean dictionaryDownloaded = false;
|
||||
|
||||
for (final DownloadRecord record : recordList) {
|
||||
// downloadSuccessful is not final because we may still have exceptions from now on
|
||||
boolean downloadSuccessful = false;
|
||||
|
@ -463,9 +465,15 @@ public final class UpdateHandler {
|
|||
final SQLiteDatabase db = MetadataDbHelper.getDb(context, record.mClientId);
|
||||
publishUpdateWordListCompleted(context, downloadSuccessful, fileId,
|
||||
db, record.mAttributes, record.mClientId);
|
||||
dictionaryDownloaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionaryDownloaded) {
|
||||
// Disable the force download after downloading the dictionaries.
|
||||
CommonPreferences.setForceDownloadDict(context, false);
|
||||
}
|
||||
// Now that we're done using it, we can remove this download from DLManager
|
||||
manager.remove(fileId);
|
||||
}
|
||||
|
@ -804,7 +812,7 @@ public final class UpdateHandler {
|
|||
} else {
|
||||
final SQLiteDatabase db = MetadataDbHelper.getDb(context, clientId);
|
||||
if (newInfo.mVersion == currentInfo.mVersion) {
|
||||
if (newInfo.mRemoteFilename == currentInfo.mRemoteFilename) {
|
||||
if (TextUtils.equals(newInfo.mRemoteFilename, currentInfo.mRemoteFilename)) {
|
||||
// If the dictionary url hasn't changed, we should preserve the retryCount.
|
||||
newInfo.mRetryCount = currentInfo.mRetryCount;
|
||||
}
|
||||
|
@ -820,7 +828,8 @@ public final class UpdateHandler {
|
|||
actions.add(new ActionBatch.MakeAvailableAction(clientId, newInfo));
|
||||
if (status == MetadataDbHelper.STATUS_INSTALLED
|
||||
|| status == MetadataDbHelper.STATUS_DISABLED) {
|
||||
actions.add(new ActionBatch.StartDownloadAction(clientId, newInfo, false));
|
||||
actions.add(new ActionBatch.StartDownloadAction(
|
||||
clientId, newInfo, CommonPreferences.isForceDownloadDict(context)));
|
||||
} else {
|
||||
// Pass true to ForgetAction: this is indeed an update to a non-installed
|
||||
// word list, so activate status == AVAILABLE check
|
||||
|
@ -973,8 +982,10 @@ 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), false));
|
||||
actions.add(new ActionBatch.StartDownloadAction(
|
||||
clientId,
|
||||
WordListMetadata.createFromContentValues(installCandidate),
|
||||
CommonPreferences.isForceDownloadDict(context)));
|
||||
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
|
||||
|
@ -1020,8 +1031,9 @@ public final class UpdateHandler {
|
|||
|| MetadataDbHelper.STATUS_DELETING == status) {
|
||||
actions.add(new ActionBatch.EnableAction(clientId, wordListMetaData));
|
||||
} else if (MetadataDbHelper.STATUS_AVAILABLE == status) {
|
||||
boolean forceDownloadDict = CommonPreferences.isForceDownloadDict(context);
|
||||
actions.add(new ActionBatch.StartDownloadAction(clientId, wordListMetaData,
|
||||
allowDownloadOnMeteredData));
|
||||
forceDownloadDict || allowDownloadOnMeteredData));
|
||||
} else {
|
||||
Log.e(TAG, "Unexpected state of the word list for markAsUsed : " + status);
|
||||
}
|
||||
|
@ -1133,7 +1145,8 @@ public final class UpdateHandler {
|
|||
context, clientId, wordlistId, version);
|
||||
|
||||
final ActionBatch actions = new ActionBatch();
|
||||
actions.add(new ActionBatch.StartDownloadAction(clientId, wordListMetaData, false));
|
||||
actions.add(new ActionBatch.StartDownloadAction(
|
||||
clientId, wordListMetaData, CommonPreferences.isForceDownloadDict(context)));
|
||||
actions.execute(context, new LogProblemReporter(TAG));
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -27,6 +27,8 @@ import android.util.Log;
|
|||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.dictionarypack.CommonPreferences;
|
||||
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
|
||||
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
|
||||
import com.android.inputmethod.latin.setup.SetupActivity;
|
||||
import com.android.inputmethod.latin.utils.UncachedInputMethodManagerUtils;
|
||||
|
@ -70,6 +72,7 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
|
|||
final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes();
|
||||
richImm.setAdditionalInputMethodSubtypes(additionalSubtypes);
|
||||
toggleAppIcon(context);
|
||||
downloadLatestDictionaries(context);
|
||||
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
|
||||
Log.i(TAG, "Boot has been completed");
|
||||
toggleAppIcon(context);
|
||||
|
@ -97,6 +100,12 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
private void downloadLatestDictionaries(Context context) {
|
||||
final Intent updateIntent = new Intent(
|
||||
DictionaryPackConstants.INIT_AND_UPDATE_NOW_INTENT_ACTION);
|
||||
context.sendBroadcast(updateIntent);
|
||||
}
|
||||
|
||||
private static void toggleAppIcon(final Context context) {
|
||||
final int appInfoFlags = context.getApplicationInfo().flags;
|
||||
final boolean isSystemApp = (appInfoFlags & ApplicationInfo.FLAG_SYSTEM) > 0;
|
||||
|
|
|
@ -22,11 +22,13 @@ import android.content.res.AssetManager;
|
|||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.latin.AssetFileAddress;
|
||||
import com.android.inputmethod.latin.BinaryDictionaryGetter;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.common.LocaleUtils;
|
||||
import com.android.inputmethod.latin.define.DecoderSpecificConstants;
|
||||
import com.android.inputmethod.latin.makedict.DictionaryHeader;
|
||||
|
@ -37,6 +39,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -69,12 +72,11 @@ public class DictionaryInfoUtils {
|
|||
public final Locale mLocale;
|
||||
@Nullable
|
||||
public final String mDescription;
|
||||
@Nonnull
|
||||
public final AssetFileAddress mFileAddress;
|
||||
public final int mVersion;
|
||||
|
||||
public DictionaryInfo(@Nonnull final String id, @Nonnull final Locale locale,
|
||||
@Nullable final String description, @Nonnull final AssetFileAddress fileAddress,
|
||||
@Nullable final String description, @Nullable final AssetFileAddress fileAddress,
|
||||
final int version) {
|
||||
mId = id;
|
||||
mLocale = locale;
|
||||
|
@ -88,10 +90,12 @@ public class DictionaryInfoUtils {
|
|||
values.put(WORDLISTID_COLUMN, mId);
|
||||
values.put(LOCALE_COLUMN, mLocale.toString());
|
||||
values.put(DESCRIPTION_COLUMN, mDescription);
|
||||
values.put(LOCAL_FILENAME_COLUMN, mFileAddress.mFilename);
|
||||
values.put(LOCAL_FILENAME_COLUMN,
|
||||
mFileAddress != null ? mFileAddress.mFilename : "");
|
||||
values.put(DATE_COLUMN, TimeUnit.MILLISECONDS.toSeconds(
|
||||
new File(mFileAddress.mFilename).lastModified()));
|
||||
values.put(FILESIZE_COLUMN, mFileAddress.mLength);
|
||||
mFileAddress != null ? new File(mFileAddress.mFilename).lastModified() : 0));
|
||||
values.put(FILESIZE_COLUMN,
|
||||
mFileAddress != null ? mFileAddress.mLength : 0);
|
||||
values.put(VERSION_COLUMN, mVersion);
|
||||
return values;
|
||||
}
|
||||
|
@ -360,7 +364,6 @@ public class DictionaryInfoUtils {
|
|||
* @param locale Locale for this file.
|
||||
* @return information of the specified dictionary.
|
||||
*/
|
||||
@Nullable
|
||||
private static DictionaryInfo createDictionaryInfoFromFileAddress(
|
||||
final AssetFileAddress fileAddress, Locale locale) {
|
||||
final String id = getMainDictId(locale);
|
||||
|
@ -370,6 +373,17 @@ public class DictionaryInfoUtils {
|
|||
return new DictionaryInfo(id, locale, description, fileAddress, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dictionary information for the given locale.
|
||||
*/
|
||||
private static DictionaryInfo createDictionaryInfoFromLocale(Locale locale) {
|
||||
final String id = getMainDictId(locale);
|
||||
final int version = -1;
|
||||
final String description = SubtypeLocaleUtils
|
||||
.getSubtypeLocaleDisplayName(locale.toString());
|
||||
return new DictionaryInfo(id, locale, description, null, version);
|
||||
}
|
||||
|
||||
private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList,
|
||||
final DictionaryInfo newElement) {
|
||||
final Iterator<DictionaryInfo> iter = dictList.iterator();
|
||||
|
@ -441,6 +455,17 @@ public class DictionaryInfoUtils {
|
|||
addOrUpdateDictInfo(dictList, dictionaryInfo);
|
||||
}
|
||||
|
||||
// Generate the dictionary information from the enabled subtypes. This will not
|
||||
// overwrite the real records.
|
||||
RichInputMethodManager.init(context);
|
||||
List<InputMethodSubtype> enabledSubtypes = RichInputMethodManager
|
||||
.getInstance().getMyEnabledInputMethodSubtypeList(true);
|
||||
for (InputMethodSubtype subtype : enabledSubtypes) {
|
||||
Locale locale = LocaleUtils.constructLocaleFromString(subtype.getLocale());
|
||||
DictionaryInfo dictionaryInfo = createDictionaryInfoFromLocale(locale);
|
||||
addOrUpdateDictInfo(dictList, dictionaryInfo);
|
||||
}
|
||||
|
||||
return dictList;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue