aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/AndroidManifest.xml18
-rw-r--r--java/res/values-pt-rPT/strings.xml4
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java60
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupActivity.java39
-rw-r--r--java/src/com/android/inputmethod/research/LogStatement.java4
-rw-r--r--java/src/com/android/inputmethod/research/LogUnit.java8
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLog.java13
-rw-r--r--native/jni/src/proximity_info.h7
-rw-r--r--native/jni/src/proximity_info_params.cpp2
-rw-r--r--native/jni/src/proximity_info_params.h2
-rw-r--r--native/jni/src/proximity_info_state.cpp43
-rw-r--r--native/jni/src/proximity_info_state.h13
-rw-r--r--native/jni/src/proximity_info_state_utils.cpp48
-rw-r--r--native/jni/src/proximity_info_state_utils.h11
-rw-r--r--native/jni/src/proximity_info_utils.h6
15 files changed, 155 insertions, 123 deletions
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index 7cf0c0332..b88c18ee5 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -20,8 +20,8 @@
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
- <uses-permission android:name="android.permission.VIBRATE"/>
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.VIBRATE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
@@ -48,23 +48,31 @@
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker" />
</service>
+ <activity android:name=".setup.SetupActivity"
+ android:label="@string/aosp_android_keyboard_ime_name"
+ android:icon="@mipmap/ic_ime_settings">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
<activity android:name="SettingsActivity" android:label="@string/english_ime_settings"
android:uiOptions="splitActionBarWhenNarrow">
<intent-filter>
- <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity android:name="com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsActivity"
android:label="@string/android_spell_checker_settings">
<intent-filter>
- <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity android:name="DebugSettingsActivity" android:label="@string/english_ime_debug_settings">
<intent-filter>
- <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 22845769b..6e650154f 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -72,10 +72,10 @@
<string name="gesture_floating_preview_text" msgid="4443240334739381053">"Pré-visual. flutuante dinâmica"</string>
<string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"Ver palavra sugerida enquanto toca"</string>
<string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string>
- <string name="label_go_key" msgid="1635148082137219148">"OK"</string>
+ <string name="label_go_key" msgid="1635148082137219148">"Ir"</string>
<string name="label_next_key" msgid="362972844525672568">"Avançar"</string>
<string name="label_previous_key" msgid="1211868118071386787">"Ant."</string>
- <string name="label_done_key" msgid="2441578748772529288">"Feito"</string>
+ <string name="label_done_key" msgid="2441578748772529288">"OK"</string>
<string name="label_send_key" msgid="2815056534433717444">"Enviar"</string>
<string name="label_pause_key" msgid="181098308428035340">"Pausa"</string>
<string name="label_wait_key" msgid="6402152600878093134">"Esp."</string>
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 879f1db49..165116ae0 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
+import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
@@ -95,23 +96,6 @@ public final class BinaryDictionaryFileDumper {
}
/**
- * Finds out whether the dictionary pack is available on this device.
- * @param context A context to get the content resolver.
- * @return whether the dictionary pack is present or not.
- */
- private static boolean isDictionaryPackPresent(final Context context) {
- final ContentResolver cr = context.getContentResolver();
- final ContentProviderClient client =
- cr.acquireContentProviderClient(getProviderUriBuilder("").build());
- if (client != null) {
- client.release();
- return true;
- } else {
- return false;
- }
- }
-
- /**
* Queries a content provider for the list of word lists for a specific locale
* available to copy into Latin IME.
*/
@@ -128,15 +112,14 @@ public final class BinaryDictionaryFileDumper {
}
final Uri dictionaryPackUri = builder.build();
- final ContentResolver resolver = context.getContentResolver();
+ final ContentProviderClient client = context.getContentResolver().
+ acquireContentProviderClient(getProviderUriBuilder("").build());
+ if (null == client) return Collections.<WordListInfo>emptyList();
try {
- final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null,
+ final Cursor c = client.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null,
null);
if (null == c) {
- if (isDictionaryPackPresent(context)) {
- reinitializeClientRecordInDictionaryContentProvider(context, resolver,
- clientId);
- }
+ reinitializeClientRecordInDictionaryContentProvider(context, client, clientId);
return Collections.<WordListInfo>emptyList();
}
if (c.getCount() <= 0 || !c.moveToFirst()) {
@@ -152,21 +135,20 @@ public final class BinaryDictionaryFileDumper {
} while (c.moveToNext());
c.close();
return list;
- } catch (IllegalArgumentException e) {
- // Any method call on the content resolver may unexpectedly crash without notice
- // if the content provider is not present (for example, while crypting a device).
- // Testing seems to indicate that ContentResolver#query() merely returns null
- // while ContentResolver#delete throws IllegalArgumentException but this is
- // undocumented, so all ContentResolver methods should be protected. A crash here is
- // dangerous because crashing here would brick any encrypted device - we need the
- // keyboard to be up and working to enter the password. So let's be as safe as possible.
- Log.e(TAG, "IllegalArgumentException: the dictionary pack can't be contacted?", e);
+ } catch (RemoteException e) {
+ // The documentation is unclear as to in which cases this may happen, but it probably
+ // happens when the content provider got suddenly killed because it crashed or because
+ // the user disabled it through Settings.
+ Log.e(TAG, "RemoteException: communication with the dictionary pack cut", e);
return Collections.<WordListInfo>emptyList();
} catch (Exception e) {
- // Just in case we hit a problem in communication with the dictionary pack.
- // We don't want to die.
- Log.e(TAG, "Exception communicating with the dictionary pack", e);
+ // A crash here is dangerous because crashing here would brick any encrypted device -
+ // we need the keyboard to be up and working to enter the password, so we don't want
+ // to die no matter what. So let's be as safe as possible.
+ Log.e(TAG, "Unexpected exception communicating with the dictionary pack", e);
return Collections.<WordListInfo>emptyList();
+ } finally {
+ client.release();
}
}
@@ -380,7 +362,7 @@ public final class BinaryDictionaryFileDumper {
}
private static void reinitializeClientRecordInDictionaryContentProvider(final Context context,
- final ContentResolver resolver, final String clientId) {
+ final ContentProviderClient client, final String clientId) throws RemoteException {
final String metadataFileUri = context.getString(R.string.dictionary_pack_metadata_uri);
if (TextUtils.isEmpty(metadataFileUri)) return;
// Tell the content provider to reset all information about this client id
@@ -388,12 +370,12 @@ public final class BinaryDictionaryFileDumper {
.appendPath(QUERY_PATH_METADATA)
.appendQueryParameter(QUERY_PARAMETER_PROTOCOL, QUERY_PARAMETER_PROTOCOL_VALUE)
.build();
- resolver.delete(metadataContentUri, null, null);
+ client.delete(metadataContentUri, null, null);
// Update the metadata URI
final ContentValues metadataValues = new ContentValues();
metadataValues.put(INSERT_METADATA_CLIENT_ID_COLUMN, clientId);
metadataValues.put(INSERT_METADATA_METADATA_URI_COLUMN, metadataFileUri);
- resolver.insert(metadataContentUri, metadataValues);
+ client.insert(metadataContentUri, metadataValues);
// Update the dictionary list.
final Uri dictionaryContentUriBase = getProviderUriBuilder(clientId)
@@ -405,7 +387,7 @@ public final class BinaryDictionaryFileDumper {
final int length = dictionaryList.size();
for (int i = 0; i < length; ++i) {
final DictionaryInfo info = dictionaryList.get(i);
- resolver.insert(Uri.withAppendedPath(dictionaryContentUriBase, info.mId),
+ client.insert(Uri.withAppendedPath(dictionaryContentUriBase, info.mId),
info.toContentValues());
}
}
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
new file mode 100644
index 000000000..fab894584
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 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.setup;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.inputmethod.latin.SettingsActivity;
+
+public final class SetupActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // TODO: Implement setup wizard.
+ final Intent intent = new Intent();
+ intent.setClass(this, SettingsActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ finish();
+ }
+}
diff --git a/java/src/com/android/inputmethod/research/LogStatement.java b/java/src/com/android/inputmethod/research/LogStatement.java
index 059146ae6..09b12fcfa 100644
--- a/java/src/com/android/inputmethod/research/LogStatement.java
+++ b/java/src/com/android/inputmethod/research/LogStatement.java
@@ -35,7 +35,7 @@ import java.io.IOException;
* associated with the {@code String[] keys} are likely to reveal information about the user. The
* actual values are stored separately.
*/
-class LogStatement {
+public class LogStatement {
private static final String TAG = LogStatement.class.getSimpleName();
private static final boolean DEBUG = false && ProductionFlag.IS_EXPERIMENTAL_DEBUG;
@@ -166,6 +166,8 @@ class LogStatement {
/**
* Write the contents out through jsonWriter.
*
+ * The JsonWriter class must have already had {@code JsonWriter.beginArray} called on it.
+ *
* Note that this method is not thread safe for the same jsonWriter. Callers must ensure
* thread safety.
*/
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index a584a3af6..1a9a720f3 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -110,7 +110,13 @@ import java.util.List;
}
/**
- * Publish the contents of this LogUnit to researchLog.
+ * Publish the contents of this LogUnit to {@code researchLog}.
+ *
+ * For each publishable {@code LogStatement}, invoke {@link LogStatement#outputToLocked}.
+ *
+ * @param researchLog where to publish the contents of this {@code LogUnit}
+ * @param canIncludePrivateData whether the private data in this {@code LogUnit} should be
+ * included
*/
public synchronized void publishTo(final ResearchLog researchLog,
final boolean canIncludePrivateData) {
diff --git a/java/src/com/android/inputmethod/research/ResearchLog.java b/java/src/com/android/inputmethod/research/ResearchLog.java
index 24bf7d15f..5114977d8 100644
--- a/java/src/com/android/inputmethod/research/ResearchLog.java
+++ b/java/src/com/android/inputmethod/research/ResearchLog.java
@@ -81,10 +81,7 @@ public class ResearchLog {
}
}
- public ResearchLog(final File outputFile, Context context) {
- if (outputFile == null) {
- throw new IllegalArgumentException();
- }
+ public ResearchLog(final File outputFile, final Context context) {
mExecutor = Executors.newSingleThreadScheduledExecutor();
mFile = outputFile;
mContext = context;
@@ -112,7 +109,7 @@ public class ResearchLog {
Log.d(TAG, "error when closing ResearchLog:");
e.printStackTrace();
} finally {
- if (mFile.exists()) {
+ if (mFile != null && mFile.exists()) {
mFile.setWritable(false, false);
}
if (onClosed != null) {
@@ -139,7 +136,9 @@ public class ResearchLog {
mHasWrittenData = false;
}
} finally {
- mIsAbortSuccessful = mFile.delete();
+ if (mFile != null) {
+ mIsAbortSuccessful = mFile.delete();
+ }
}
return null;
}
@@ -209,7 +208,7 @@ public class ResearchLog {
*/
public JsonWriter getValidJsonWriterLocked() {
try {
- if (mJsonWriter == NULL_JSON_WRITER) {
+ if (mJsonWriter == NULL_JSON_WRITER && mFile != null) {
final FileOutputStream fos =
mContext.openFileOutput(mFile.getName(), Context.MODE_PRIVATE);
mJsonWriter = new JsonWriter(new BufferedWriter(new OutputStreamWriter(fos)));
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index ee79367ef..22bbdf165 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -70,15 +70,16 @@ class ProximityInfo {
int getKeyCenterYOfKeyIdG(int keyId) const;
int getKeyKeyDistanceG(int keyId0, int keyId1) const;
- void initializeProximities(const int *const inputCodes, const int *const inputXCoordinates,
- const int *const inputYCoordinates, const int inputSize, int *allInputCodes) const {
+ void AK_FORCE_INLINE initializeProximities(const int *const inputCodes,
+ const int *const inputXCoordinates, const int *const inputYCoordinates,
+ const int inputSize, int *allInputCodes) const {
ProximityInfoUtils::initializeProximities(inputCodes, inputXCoordinates, inputYCoordinates,
inputSize, mKeyXCoordinates, mKeyYCoordinates, mKeyWidths, mKeyHeights,
mProximityCharsArray, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH, MOST_COMMON_KEY_WIDTH,
KEY_COUNT, mLocaleStr, &mCodeToKeyMap, allInputCodes);
}
- int getKeyIndexOf(const int c) const {
+ int AK_FORCE_INLINE getKeyIndexOf(const int c) const {
return ProximityInfoUtils::getKeyIndexOf(KEY_COUNT, c, &mCodeToKeyMap);
}
diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp
index 1410ab575..f9a4352ee 100644
--- a/native/jni/src/proximity_info_params.cpp
+++ b/native/jni/src/proximity_info_params.cpp
@@ -88,7 +88,7 @@ const float ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN =
// Used by ProximityInfoStateUtils::getMostProbableString()
const float ProximityInfoParams::DEMOTION_LOG_PROBABILITY = 0.3f;
-// Used by ProximityInfoStateUtils::updateSampledSearchKeysVector()
+// Used by ProximityInfoStateUtils::updateSampledSearchKeySets()
// TODO: Investigate if this is required
const float ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO = 0.95f;
diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h
index 7c26208a8..e7aec0976 100644
--- a/native/jni/src/proximity_info_params.h
+++ b/native/jni/src/proximity_info_params.h
@@ -90,7 +90,7 @@ class ProximityInfoParams {
// Used by ProximityInfoStateUtils::getMostProbableString()
static const float DEMOTION_LOG_PROBABILITY;
- // Used by ProximityInfoStateUtils::updateSampledSearchKeysVector()
+ // Used by ProximityInfoStateUtils::updateSampledSearchKeySets()
static const float SEARCH_KEY_RADIUS_RATIO;
// Used by ProximityInfoStateUtils::calculateBeelineSpeedRate()
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 4c1ffb30e..bdbf8b170 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -16,6 +16,7 @@
#include <cstring> // for memset() and memcpy()
#include <sstream> // for debug prints
+#include <vector>
#define LOG_TAG "LatinIME: proximity_info_state.cpp"
@@ -75,8 +76,8 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mSampledInputIndice.clear();
mSampledLengthCache.clear();
mSampledDistanceCache_G.clear();
- mSampledNearKeysVector.clear();
- mSampledSearchKeysVector.clear();
+ mSampledNearKeySets.clear();
+ mSampledSearchKeySets.clear();
mSpeedRates.clear();
mBeelineSpeedPercentiles.clear();
mCharProbabilities.clear();
@@ -109,7 +110,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
if (mSampledInputSize > 0) {
ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize,
- lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeysVector,
+ lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeySets,
&mSampledDistanceCache_G);
if (isGeometric) {
// updates probabilities of skipping or mapping each key for all points.
@@ -117,10 +118,11 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
mMaxPointToKeyLength, mProximityInfo->getMostCommonKeyWidth(),
mProximityInfo->getKeyCount(), lastSavedInputSize, mSampledInputSize,
&mSampledInputXs, &mSampledInputYs, &mSpeedRates, &mSampledLengthCache,
- &mSampledDistanceCache_G, &mSampledNearKeysVector, &mCharProbabilities);
- ProximityInfoStateUtils::updateSampledSearchKeysVector(mProximityInfo,
+ &mSampledDistanceCache_G, &mSampledNearKeySets, &mCharProbabilities);
+ ProximityInfoStateUtils::updateSampledSearchKeySets(mProximityInfo,
mSampledInputSize, lastSavedInputSize, &mSampledLengthCache,
- &mSampledNearKeysVector, &mSampledSearchKeysVector);
+ &mSampledNearKeySets, &mSampledSearchKeySets,
+ &mSampledSearchKeyVectors);
mMostProbableStringProbability = ProximityInfoStateUtils::getMostProbableString(
mProximityInfo, mSampledInputSize, &mCharProbabilities, mMostProbableString);
@@ -245,36 +247,9 @@ ProximityType ProximityInfoState::getMatchedProximityId(const int index, const i
return UNRELATED_CHAR;
}
-// Puts possible characters into filter and returns new filter size.
-int ProximityInfoState::getAllPossibleChars(
- const size_t index, int *const filter, const int filterSize) const {
- if (index >= mSampledInputXs.size()) {
- return filterSize;
- }
- int newFilterSize = filterSize;
- const int keyCount = mProximityInfo->getKeyCount();
- for (int j = 0; j < keyCount; ++j) {
- if (mSampledSearchKeysVector[index].test(j)) {
- const int keyCodePoint = mProximityInfo->getCodePointOf(j);
- bool insert = true;
- // TODO: Avoid linear search
- for (int k = 0; k < filterSize; ++k) {
- if (filter[k] == keyCodePoint) {
- insert = false;
- break;
- }
- }
- if (insert) {
- filter[newFilterSize++] = keyCodePoint;
- }
- }
- }
- return newFilterSize;
-}
-
bool ProximityInfoState::isKeyInSerchKeysAfterIndex(const int index, const int keyId) const {
ASSERT(keyId >= 0 && index >= 0 && index < mSampledInputSize);
- return mSampledSearchKeysVector[index].test(keyId);
+ return mSampledSearchKeySets[index].test(keyId);
}
float ProximityInfoState::getDirection(const int index0, const int index1) const {
diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h
index 0386450bd..c4cbd582d 100644
--- a/native/jni/src/proximity_info_state.h
+++ b/native/jni/src/proximity_info_state.h
@@ -50,7 +50,7 @@ class ProximityInfoState {
mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mSampledTimes(),
mSampledInputIndice(), mSampledLengthCache(), mBeelineSpeedPercentiles(),
mSampledDistanceCache_G(), mSpeedRates(), mDirections(), mCharProbabilities(),
- mSampledNearKeysVector(), mSampledSearchKeysVector(),
+ mSampledNearKeySets(), mSampledSearchKeySets(), mSampledSearchKeyVectors(),
mTouchPositionCorrectionEnabled(false), mSampledInputSize(0),
mMostProbableStringProbability(0.0f) {
memset(mInputProximities, 0, sizeof(mInputProximities));
@@ -155,7 +155,9 @@ class ProximityInfoState {
ProximityType getMatchedProximityId(const int index, const int c,
const bool checkProximityChars, int *proximityIndex = 0) const;
- int getAllPossibleChars(const size_t startIndex, int *const filter, const int filterSize) const;
+ const std::vector<int> *getSearchKeyVector(const int index) const {
+ return &mSampledSearchKeyVectors[index];
+ }
float getSpeedRate(const int index) const {
return mSpeedRates[index];
@@ -236,13 +238,14 @@ class ProximityInfoState {
std::vector<hash_map_compat<int, float> > mCharProbabilities;
// The vector for the key code set which holds nearby keys for each sampled input point
// 1. Used to calculate the probability of the key
- // 2. Used to calculate mSampledSearchKeysVector
- std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledNearKeysVector;
+ // 2. Used to calculate mSampledSearchKeySets
+ std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledNearKeySets;
// The vector for the key code set which holds nearby keys of some trailing sampled input points
// for each sampled input point. These nearby keys contain the next characters which can be in
// the dictionary. Specifically, currently we are looking for keys nearby trailing sampled
// inputs including the current input point.
- std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledSearchKeysVector;
+ std::vector<ProximityInfoStateUtils::NearKeycodesSet> mSampledSearchKeySets;
+ std::vector<std::vector<int> > mSampledSearchKeyVectors;
bool mTouchPositionCorrectionEnabled;
int mInputProximities[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
int mNormalizedSquaredDistances[MAX_PROXIMITY_CHARS_SIZE * MAX_WORD_LENGTH];
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index f9b69d264..2bf327fcc 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -224,13 +224,13 @@ namespace latinime {
const ProximityInfo *const proximityInfo, const int sampledInputSize,
const int lastSavedInputSize, const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
- std::vector<NearKeycodesSet> *SampledNearKeysVector,
+ std::vector<NearKeycodesSet> *SampledNearKeySets,
std::vector<float> *SampledDistanceCache_G) {
- SampledNearKeysVector->resize(sampledInputSize);
+ SampledNearKeySets->resize(sampledInputSize);
const int keyCount = proximityInfo->getKeyCount();
SampledDistanceCache_G->resize(sampledInputSize * keyCount);
for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
- (*SampledNearKeysVector)[i].reset();
+ (*SampledNearKeySets)[i].reset();
for (int k = 0; k < keyCount; ++k) {
const int index = i * keyCount + k;
const int x = (*sampledInputXs)[i];
@@ -240,7 +240,7 @@ namespace latinime {
(*SampledDistanceCache_G)[index] = normalizedSquaredDistance;
if (normalizedSquaredDistance
< ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD) {
- (*SampledNearKeysVector)[i][k] = true;
+ (*SampledNearKeySets)[i][k] = true;
}
}
}
@@ -664,7 +664,7 @@ namespace latinime {
const std::vector<float> *const sampledSpeedRates,
const std::vector<int> *const sampledLengthCache,
const std::vector<float> *const SampledDistanceCache_G,
- std::vector<NearKeycodesSet> *SampledNearKeysVector,
+ std::vector<NearKeycodesSet> *SampledNearKeySets,
std::vector<hash_map_compat<int, float> > *charProbabilities) {
charProbabilities->resize(sampledInputSize);
// Calculates probabilities of using a point as a correlated point with the character
@@ -680,7 +680,7 @@ namespace latinime {
float nearestKeyDistance = static_cast<float>(MAX_POINT_TO_KEY_LENGTH);
for (int j = 0; j < keyCount; ++j) {
- if ((*SampledNearKeysVector)[i].test(j)) {
+ if ((*SampledNearKeySets)[i].test(j)) {
const float distance = getPointToKeyByIdLength(
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i, j);
if (distance < nearestKeyDistance) {
@@ -761,7 +761,7 @@ namespace latinime {
// Summing up probability densities of all near keys.
float sumOfProbabilityDensities = 0.0f;
for (int j = 0; j < keyCount; ++j) {
- if ((*SampledNearKeysVector)[i].test(j)) {
+ if ((*SampledNearKeySets)[i].test(j)) {
float distance = sqrtf(getPointToKeyByIdLength(
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i, j));
if (i == 0 && i != sampledInputSize - 1) {
@@ -801,7 +801,7 @@ namespace latinime {
// Split the probability of an input point to keys that are close to the input point.
for (int j = 0; j < keyCount; ++j) {
- if ((*SampledNearKeysVector)[i].test(j)) {
+ if ((*SampledNearKeySets)[i].test(j)) {
float distance = sqrtf(getPointToKeyByIdLength(
maxPointToKeyLength, SampledDistanceCache_G, keyCount, i, j));
if (i == 0 && i != sampledInputSize - 1) {
@@ -885,10 +885,10 @@ namespace latinime {
for (int j = 0; j < keyCount; ++j) {
hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
if (it == (*charProbabilities)[i].end()){
- (*SampledNearKeysVector)[i].reset(j);
+ (*SampledNearKeySets)[i].reset(j);
} else if(it->second < ProximityInfoParams::MIN_PROBABILITY) {
// Erases from near keys vector because it has very low probability.
- (*SampledNearKeysVector)[i].reset(j);
+ (*SampledNearKeySets)[i].reset(j);
(*charProbabilities)[i].erase(j);
} else {
it->second = -logf(it->second);
@@ -898,26 +898,42 @@ namespace latinime {
}
}
-/* static */ void ProximityInfoStateUtils::updateSampledSearchKeysVector(
+/* static */ void ProximityInfoStateUtils::updateSampledSearchKeySets(
const ProximityInfo *const proximityInfo, const int sampledInputSize,
const int lastSavedInputSize,
const std::vector<int> *const sampledLengthCache,
- const std::vector<NearKeycodesSet> *const SampledNearKeysVector,
- std::vector<NearKeycodesSet> *sampledSearchKeysVector) {
- sampledSearchKeysVector->resize(sampledInputSize);
+ const std::vector<NearKeycodesSet> *const SampledNearKeySets,
+ std::vector<NearKeycodesSet> *sampledSearchKeySets,
+ std::vector<std::vector<int> > *sampledSearchKeyVectors) {
+ sampledSearchKeySets->resize(sampledInputSize);
+ sampledSearchKeyVectors->resize(sampledInputSize);
const int readForwordLength = static_cast<int>(
hypotf(proximityInfo->getKeyboardWidth(), proximityInfo->getKeyboardHeight())
* ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO);
for (int i = 0; i < sampledInputSize; ++i) {
if (i >= lastSavedInputSize) {
- (*sampledSearchKeysVector)[i].reset();
+ (*sampledSearchKeySets)[i].reset();
}
for (int j = max(i, lastSavedInputSize); j < sampledInputSize; ++j) {
// TODO: Investigate if this is required. This may not fail.
if ((*sampledLengthCache)[j] - (*sampledLengthCache)[i] >= readForwordLength) {
break;
}
- (*sampledSearchKeysVector)[i] |= (*SampledNearKeysVector)[j];
+ (*sampledSearchKeySets)[i] |= (*SampledNearKeySets)[j];
+ }
+ }
+ const int keyCount = proximityInfo->getKeyCount();
+ for (int i = 0; i < sampledInputSize; ++i) {
+ std::vector<int> *searchKeyVector = &(*sampledSearchKeyVectors)[i];
+ searchKeyVector->clear();
+ for (int j = 0; j < keyCount; ++j) {
+ if ((*sampledSearchKeySets)[i].test(j)) {
+ const int keyCodePoint = proximityInfo->getCodePointOf(j);
+ if (std::find(searchKeyVector->begin(), searchKeyVector->end(), keyCodePoint)
+ == searchKeyVector->end()) {
+ searchKeyVector->push_back(keyCodePoint);
+ }
+ }
}
}
}
diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h
index af0acc788..d55730aca 100644
--- a/native/jni/src/proximity_info_state_utils.h
+++ b/native/jni/src/proximity_info_state_utils.h
@@ -71,13 +71,14 @@ class ProximityInfoStateUtils {
const std::vector<float> *const sampledSpeedRates,
const std::vector<int> *const sampledLengthCache,
const std::vector<float> *const SampledDistanceCache_G,
- std::vector<NearKeycodesSet> *SampledNearKeysVector,
+ std::vector<NearKeycodesSet> *SampledNearKeySets,
std::vector<hash_map_compat<int, float> > *charProbabilities);
- static void updateSampledSearchKeysVector(const ProximityInfo *const proximityInfo,
+ static void updateSampledSearchKeySets(const ProximityInfo *const proximityInfo,
const int sampledInputSize, const int lastSavedInputSize,
const std::vector<int> *const sampledLengthCache,
- const std::vector<NearKeycodesSet> *const SampledNearKeysVector,
- std::vector<NearKeycodesSet> *sampledSearchKeysVector);
+ const std::vector<NearKeycodesSet> *const SampledNearKeySets,
+ std::vector<NearKeycodesSet> *sampledSearchKeySets,
+ std::vector<std::vector<int> > *sampledSearchKeyVectors);
static float getPointToKeyByIdLength(const float maxPointToKeyLength,
const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
const int inputIndex, const int keyId, const float scale);
@@ -88,7 +89,7 @@ class ProximityInfoStateUtils {
const int sampledInputSize, const int lastSavedInputSize,
const std::vector<int> *const sampledInputXs,
const std::vector<int> *const sampledInputYs,
- std::vector<NearKeycodesSet> *SampledNearKeysVector,
+ std::vector<NearKeycodesSet> *SampledNearKeySets,
std::vector<float> *SampledDistanceCache_G);
static void initPrimaryInputWord(const int inputSize, const int *const inputProximities,
int *primaryInputWord);
diff --git a/native/jni/src/proximity_info_utils.h b/native/jni/src/proximity_info_utils.h
index c50df57f9..51cafba2c 100644
--- a/native/jni/src/proximity_info_utils.h
+++ b/native/jni/src/proximity_info_utils.h
@@ -28,7 +28,7 @@
namespace latinime {
class ProximityInfoUtils {
public:
- static int getKeyIndexOf(const int keyCount, const int c,
+ static AK_FORCE_INLINE int getKeyIndexOf(const int keyCount, const int c,
const hash_map_compat<int, int> *const codeToKeyMap) {
if (keyCount == 0) {
// We do not have the coordinate data
@@ -45,7 +45,7 @@ class ProximityInfoUtils {
return NOT_AN_INDEX;
}
- static void initializeProximities(const int *const inputCodes,
+ static AK_FORCE_INLINE void initializeProximities(const int *const inputCodes,
const int *const inputXCoordinates, const int *const inputYCoordinates,
const int inputSize, const int *const keyXCoordinates,
const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
@@ -151,7 +151,7 @@ class ProximityInfoUtils {
return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
}
- static void calculateProximities(const int *const keyXCoordinates,
+ static AK_FORCE_INLINE void calculateProximities(const int *const keyXCoordinates,
const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
const int *const proximityCharsArray, const int cellHeight, const int cellWidth,
const int gridWidth, const int mostCommonKeyWidth, const int keyCount,