diff options
-rw-r--r-- | java/AndroidManifest.xml | 18 | ||||
-rw-r--r-- | java/res/values-pt-rPT/strings.xml | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java | 60 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/setup/SetupActivity.java | 39 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/research/LogStatement.java | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/research/LogUnit.java | 8 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/research/ResearchLog.java | 13 | ||||
-rw-r--r-- | native/jni/src/proximity_info.h | 7 | ||||
-rw-r--r-- | native/jni/src/proximity_info_params.cpp | 2 | ||||
-rw-r--r-- | native/jni/src/proximity_info_params.h | 2 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.cpp | 43 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state.h | 13 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state_utils.cpp | 48 | ||||
-rw-r--r-- | native/jni/src/proximity_info_state_utils.h | 11 | ||||
-rw-r--r-- | native/jni/src/proximity_info_utils.h | 6 |
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, |