aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/AndroidManifest.xml1
-rw-r--r--java/res/values/config-dictionary-pack.xml4
-rw-r--r--java/res/values/strings.xml6
-rw-r--r--java/res/xml/method.xml2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/ActionBatch.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/CommonPreferences.java12
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryService.java18
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java64
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java25
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java4
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java8
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryStats.java55
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java27
-rw-r--r--java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java9
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java19
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsActivity.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java16
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java37
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java82
20 files changed, 212 insertions, 183 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index 210d9a964..f58c401c7 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -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>
diff --git a/java/res/values/config-dictionary-pack.xml b/java/res/values/config-dictionary-pack.xml
index d076af452..bf52de88b 100644
--- a/java/res/values/config-dictionary-pack.xml
+++ b/java/res/values/config-dictionary-pack.xml
@@ -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>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 54579f2d6..5655a5529 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -62,9 +62,9 @@
<string name="cloud_sync_summary_disabled">Sync your personal dictionary across devices</string>
<!-- Option title for starting the sync cycle now. [CHAR LIMIT=33]-->
<string name="sync_now_title">Sync now</string>
- <!-- Option title for letting user delete data from Google servers. [CHAR LIMIT=33] -->
- <string name="clear_sync_data_title">Delete Keyboard Cloud data</string>
- <!-- Option summary for letting user delete data from Google servers. [CHAR LIMIT=65] -->
+ <!-- Option title for letting user delete synced google keyboard data from Google servers. [CHAR LIMIT=35] -->
+ <string name="clear_sync_data_title">Delete cloud data</string>
+ <!-- Option summary for letting user delete synced google keyboard data from Google servers. [CHAR LIMIT=65] -->
<string name="clear_sync_data_summary">Deletes your synced data from Google</string>
<!-- Text for confirmation dialog box asking user to confirm deletion of cloud data. [CHAR LIMIT=65] -->
<string name="clear_sync_data_confirmation">Your synced data will be deleted from the cloud. Are you sure?</string>
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 64929adf1..0b0c93e84 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -366,6 +366,7 @@
/>
<!-- TODO: This Hinglish keyboard is a preliminary layout.
This isn't based on the final specification. -->
+ <!-- Disabled because there is no LM yet, and this layout does not offer anything different.
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_hi_ZZ"
android:subtypeId="0x352eb37c"
@@ -374,6 +375,7 @@
android:imeSubtypeExtraValue="AsciiCapable,KeyboardLayoutSet=qwerty,EmojiCapable"
android:isAsciiCapable="true"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35b7526a"
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
index 12fdd69b9..ee142d845 100644
--- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
+++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
@@ -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);
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/CommonPreferences.java b/java/src/com/android/inputmethod/dictionarypack/CommonPreferences.java
index 3d0e29ed0..3cd822a3c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/CommonPreferences.java
+++ b/java/src/com/android/inputmethod/dictionarypack/CommonPreferences.java
@@ -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();
+ }
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
index c678f081d..bbdf2a380 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryService.java
@@ -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));
}
/**
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
index 14e005007..88ea4e6c3 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
@@ -28,6 +28,7 @@ import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
@@ -106,16 +107,27 @@ public final class DictionarySettingsFragment extends PreferenceFragment
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
- final String metadataUri =
- MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId);
- // We only add the "Refresh" button if we have a non-empty URL to refresh from. If the
- // URL is empty, of course we can't refresh so it makes no sense to display this.
- if (!TextUtils.isEmpty(metadataUri)) {
- mUpdateNowMenu =
- menu.add(Menu.NONE, MENU_UPDATE_NOW, 0, R.string.check_for_updates_now);
- mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- refreshNetworkState();
- }
+ new AsyncTask<Void, Void, String>() {
+ @Override
+ protected String doInBackground(Void... params) {
+ return MetadataDbHelper.getMetadataUriAsString(getActivity(), mClientId);
+ }
+
+ @Override
+ protected void onPostExecute(String metadataUri) {
+ // We only add the "Refresh" button if we have a non-empty URL to refresh from. If
+ // the URL is empty, of course we can't refresh so it makes no sense to display
+ // this.
+ if (!TextUtils.isEmpty(metadataUri)) {
+ if (mUpdateNowMenu == null) {
+ mUpdateNowMenu = menu.add(Menu.NONE, MENU_UPDATE_NOW, 0,
+ R.string.check_for_updates_now);
+ mUpdateNowMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ }
+ refreshNetworkState();
+ }
+ }
+ }.execute();
}
@Override
@@ -124,18 +136,25 @@ public final class DictionarySettingsFragment extends PreferenceFragment
mChangedSettings = false;
UpdateHandler.registerUpdateEventListener(this);
final Activity activity = getActivity();
- if (!MetadataDbHelper.isClientKnown(activity, mClientId)) {
- Log.i(TAG, "Unknown dictionary pack client: " + mClientId + ". Requesting info.");
- final Intent unknownClientBroadcast =
- new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT);
- unknownClientBroadcast.putExtra(
- DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId);
- activity.sendBroadcast(unknownClientBroadcast);
- }
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getActivity().registerReceiver(mConnectivityChangedReceiver, filter);
refreshNetworkState();
+
+ new Thread("onResume") {
+ @Override
+ public void run() {
+ if (!MetadataDbHelper.isClientKnown(activity, mClientId)) {
+ Log.i(TAG, "Unknown dictionary pack client: " + mClientId
+ + ". Requesting info.");
+ final Intent unknownClientBroadcast =
+ new Intent(DictionaryPackConstants.UNKNOWN_DICTIONARY_PROVIDER_CLIENT);
+ unknownClientBroadcast.putExtra(
+ DictionaryPackConstants.DICTIONARY_PROVIDER_CLIENT_EXTRA, mClientId);
+ activity.sendBroadcast(unknownClientBroadcast);
+ }
+ }
+ }.start();
}
@Override
@@ -375,8 +394,13 @@ public final class DictionarySettingsFragment extends PreferenceFragment
private void cancelRefresh() {
UpdateHandler.unregisterUpdateEventListener(this);
final Context context = getActivity();
- UpdateHandler.cancelUpdate(context, mClientId);
- stopLoadingAnimation();
+ new Thread("cancelByHand") {
+ @Override
+ public void run() {
+ UpdateHandler.cancelUpdate(context, mClientId);
+ stopLoadingAnimation();
+ }
+ }.start();
}
private void startLoadingAnimation() {
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index b00a811bb..a2789cc1a 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -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) {
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index f05db9dab..30ff0b8ee 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -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) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 6b49f9aa6..d5dff10db 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.latin;
import android.content.Context;
-import android.util.Pair;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Keyboard;
@@ -28,6 +27,7 @@ import com.android.inputmethod.latin.utils.SuggestionResults;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -172,5 +172,5 @@ public interface DictionaryFacilitator {
void dumpDictionaryForDebug(final String dictName);
- ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts();
+ @Nonnull List<DictionaryStats> getDictionaryStats(final Context context);
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index e5d770aee..9ce92da9e 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Keyboard;
@@ -39,6 +38,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -644,12 +644,12 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
@Override
- public ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts() {
- final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
+ @Nonnull public List<DictionaryStats> getDictionaryStats(final Context context) {
+ final ArrayList<DictionaryStats> statsOfEnabledSubDicts = new ArrayList<>();
for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictType);
if (dictionary == null) continue;
- statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
+ statsOfEnabledSubDicts.add(dictionary.getDictionaryStats());
}
return statsOfEnabledSubDicts;
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryStats.java b/java/src/com/android/inputmethod/latin/DictionaryStats.java
index 5dd39d3d6..a6b37aa8f 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryStats.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryStats.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin;
import java.io.File;
+import java.math.BigDecimal;
import java.util.Locale;
public class DictionaryStats {
@@ -26,18 +27,54 @@ public class DictionaryStats {
public final String mDictName;
public final String mDictFilePath;
public final long mDictFileSize;
-
- public final int mUnigramCount;
- public final int mNgramCount;
- // TODO: Add more members.
+ public final int mContentVersion;
public DictionaryStats(final Locale locale, final String dictName, final File dictFile,
- final int unigramCount, final int ngramCount) {
+ final int contentVersion) {
mLocale = locale;
mDictName = dictName;
- mDictFilePath = dictFile.getAbsolutePath();
- mDictFileSize = dictFile.length();
- mUnigramCount = unigramCount;
- mNgramCount = ngramCount;
+ mDictFilePath = (dictFile == null) ? null : dictFile.getName();
+ mDictFileSize = (dictFile == null || !dictFile.exists()) ? 0 : dictFile.length();
+ mContentVersion = contentVersion;
+ }
+
+ public String getFileSizeString() {
+ if (mDictFileSize == 0) {
+ return "0";
+ }
+ BigDecimal bytes = new BigDecimal(mDictFileSize);
+ BigDecimal kb = bytes.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP);
+ if (kb.longValue() == 0) {
+ return bytes.toString() + " bytes";
+ }
+ BigDecimal mb = kb.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP);
+ if (mb.longValue() == 0) {
+ return kb.toString() + " kb";
+ }
+ return mb.toString() + " Mb";
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder(mDictName);
+ if (mDictName.equals(Dictionary.TYPE_MAIN)) {
+ builder.append(" (");
+ builder.append(mContentVersion);
+ builder.append(")");
+ }
+ builder.append(": ");
+ builder.append(mDictFilePath);
+ builder.append(" / ");
+ builder.append(getFileSizeString());
+ return builder.toString();
+ }
+
+ public static String toString(final Iterable<DictionaryStats> stats) {
+ final StringBuilder builder = new StringBuilder("LM Stats");
+ for (DictionaryStats stat : stats) {
+ builder.append("\n ");
+ builder.append(stat.toString());
+ }
+ return builder.toString();
}
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 80daedd50..1ef7061fb 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -646,16 +646,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
- static int parseEntryCount(final String entryCountStr) {
- int entryCount;
- try {
- entryCount = Integer.parseInt(entryCountStr);
- } catch (final NumberFormatException e) {
- entryCount = DictionaryStats.NOT_AN_ENTRY_COUNT;
- }
- return entryCount;
- }
-
public DictionaryStats getDictionaryStats() {
reloadDictionaryIfRequired();
final String dictName = mDictName;
@@ -664,22 +654,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() {
@Override
public void run() {
- final BinaryDictionary binaryDictionary = getBinaryDictionary();
- if (binaryDictionary == null) {
- result.set(new DictionaryStats(mLocale, dictName, dictFile,
- DictionaryStats.NOT_AN_ENTRY_COUNT,
- DictionaryStats.NOT_AN_ENTRY_COUNT));
- return;
- }
- final int unigramCount = parseEntryCount(
- binaryDictionary.getPropertyForGettingStats(
- BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
- // TODO: Get dedicated entry counts for bigram, trigram, and so on.
- final int ngramCount = parseEntryCount(binaryDictionary.getPropertyForGettingStats(
- BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
- // TODO: Get more information from dictionary.
- result.set(new DictionaryStats(mLocale, dictName, dictFile, unigramCount,
- ngramCount));
+ result.set(new DictionaryStats(mLocale, dictName, dictFile, 0));
}
});
return result.get(null /* defaultValue */, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
index 5c3abd2db..2a69d3650 100644
--- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
@@ -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;
diff --git a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
index f7c5f6760..62834cd2a 100644
--- a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
@@ -49,7 +49,7 @@ import java.util.TreeSet;
*/
public final class CorrectionSettingsFragment extends SubScreenFragment {
private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false;
- private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS =
+ private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS =
DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
|| Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2;
@@ -61,8 +61,6 @@ public final class CorrectionSettingsFragment extends SubScreenFragment {
final Context context = getActivity();
final PackageManager pm = context.getPackageManager();
- ensureConsistencyOfAutoCorrectionSettings();
-
final Preference dictionaryLink = findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
final Intent intent = dictionaryLink.getIntent();
intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName());
@@ -74,7 +72,7 @@ public final class CorrectionSettingsFragment extends SubScreenFragment {
final Preference editPersonalDictionary =
findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
- final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS ? null
+ final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS ? null
: pm.resolveActivity(
editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (ri == null) {
@@ -82,19 +80,6 @@ public final class CorrectionSettingsFragment extends SubScreenFragment {
}
}
- @Override
- public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
- ensureConsistencyOfAutoCorrectionSettings();
- }
-
- private void ensureConsistencyOfAutoCorrectionSettings() {
- final TwoStatePreference autoCorrectionPref = (TwoStatePreference)
- findPreference(Settings.PREF_AUTO_CORRECTION);
- if (!autoCorrectionPref.isChecked()) {
- setPreferenceEnabled(Settings.PREF_BIGRAM_PREDICTIONS, false);
- }
- }
-
private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) {
final Activity activity = getActivity();
final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
index dee4811c9..9975277e4 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
@@ -50,7 +50,7 @@ public final class SettingsActivity extends PreferenceActivity {
}
StatsUtils.onSettingsActivity(
intent.hasExtra(EXTRA_ENTRY_KEY) ? intent.getStringExtra(EXTRA_ENTRY_KEY)
- : intent.getStringExtra(EXTRA_ENTRY_VALUE_SYSTEM_SETTINGS));
+ : EXTRA_ENTRY_VALUE_SYSTEM_SETTINGS);
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index b98c53af4..f5455e3db 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -16,10 +16,12 @@
package com.android.inputmethod.latin.settings;
+import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
+import android.provider.Settings.Secure;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -68,13 +70,23 @@ public final class SettingsFragment extends InputMethodSettingsFragment {
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
+ final Activity activity = getActivity();
+ final int setupStatus = Secure.getInt(
+ activity.getContentResolver(),
+ "user_setup_complete",
+ 0 /* default */);
+ if (setupStatus == 0) {
+ // If setup is not complete, it's not safe to launch Help or other activities
+ // because they might go to the Play Store. See b/19866981.
+ return true;
+ }
final int itemId = item.getItemId();
if (itemId == MENU_HELP_AND_FEEDBACK) {
- FeedbackUtils.showHelpAndFeedbackForm(getActivity());
+ FeedbackUtils.showHelpAndFeedbackForm(activity);
return true;
}
if (itemId == MENU_ABOUT) {
- final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(getActivity());
+ final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(activity);
if (aboutIntent != null) {
startActivity(aboutIntent);
return true;
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index fd567f49d..d8e332370 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -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;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java b/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java
deleted file mode 100644
index 1bd8f314c..000000000
--- a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-
-import java.util.List;
-
-/**
- * Utility for determining if the device has managed profiles.
- */
-public class ManagedProfileUtils {
- private static final boolean DEBUG = false;
- private static final String TAG = ManagedProfileUtils.class.getSimpleName();
-
- private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils();
- private static ManagedProfileUtils sTestInstance;
-
- private ManagedProfileUtils() {
- // This utility class is not publicly instantiable.
- }
-
- @UsedForTesting
- public static void setTestInstance(final ManagedProfileUtils testInstance) {
- sTestInstance = testInstance;
- }
-
- public static ManagedProfileUtils getInstance() {
- return sTestInstance == null ? INSTANCE : sTestInstance;
- }
-
- /**
- * Note that {@link UserManager#getUserProfiles} has been introduced
- * in API level 21 (Build.VERSION_CODES.LOLLIPOP).
- */
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public boolean hasManagedWorkProfile(final Context context) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- return false;
- }
-
- final UserManager userManagerService =
- (UserManager) context.getSystemService(Context.USER_SERVICE);
- if (userManagerService != null) {
- if (DEBUG) {
- Log.d(TAG, "Detecting managed profile...");
- }
- final List<UserHandle> userProfiles = userManagerService.getUserProfiles();
- if (userProfiles.size() > 1) {
- if (DEBUG) {
- Log.d(TAG, "More than one user profile => Managed profile exists.");
- }
- return true;
- }
- }
- if (DEBUG) {
- Log.d(TAG, "Managed profile not detected.");
- }
- return false;
- }
-}