diff options
Diffstat (limited to 'java/src')
15 files changed, 268 insertions, 244 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java index be9f87930..3bed2c7a0 100644 --- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java @@ -28,7 +28,7 @@ import android.util.Log; import com.android.inputmethod.compat.DownloadManagerCompatUtils; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.Utils; import java.util.LinkedList; @@ -100,7 +100,7 @@ public final class ActionBatch { final boolean mForceStartNow; public StartDownloadAction(final String clientId, final WordListMetadata wordList, final boolean forceStartNow) { - LogUtils.l("New download action for client ", clientId, " : ", wordList); + DebugLogUtils.l("New download action for client ", clientId, " : ", wordList); mClientId = clientId; mWordList = wordList; mForceStartNow = forceStartNow; @@ -112,7 +112,7 @@ public final class ActionBatch { Log.e(TAG, "UpdateAction with a null parameter!"); return; } - LogUtils.l("Downloading word list"); + DebugLogUtils.l("Downloading word list"); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -134,7 +134,7 @@ public final class ActionBatch { + " for an upgrade action. Fall back to download."); } // Download it. - LogUtils.l("Upgrade word list, downloading", mWordList.mRemoteFilename); + DebugLogUtils.l("Upgrade word list, downloading", mWordList.mRemoteFilename); // TODO: if DownloadManager is disabled or not installed, download by ourselves if (null == manager) return; @@ -180,7 +180,7 @@ public final class ActionBatch { final long downloadId = UpdateHandler.registerDownloadRequest(manager, request, db, mWordList.mId, mWordList.mVersion); - LogUtils.l("Starting download of", uri, "with id", downloadId); + DebugLogUtils.l("Starting download of", uri, "with id", downloadId); PrivateLog.log("Starting download of " + uri + ", id : " + downloadId); } } @@ -197,7 +197,7 @@ public final class ActionBatch { public InstallAfterDownloadAction(final String clientId, final ContentValues wordListValues) { - LogUtils.l("New InstallAfterDownloadAction for client ", clientId, " : ", + DebugLogUtils.l("New InstallAfterDownloadAction for client ", clientId, " : ", wordListValues); mClientId = clientId; mWordListValues = wordListValues; @@ -216,7 +216,7 @@ public final class ActionBatch { + " for an InstallAfterDownload action. Bailing out."); return; } - LogUtils.l("Setting word list as installed"); + DebugLogUtils.l("Setting word list as installed"); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); MetadataDbHelper.markEntryAsFinishedDownloadingAndInstalled(db, mWordListValues); } @@ -232,7 +232,7 @@ public final class ActionBatch { final WordListMetadata mWordList; public EnableAction(final String clientId, final WordListMetadata wordList) { - LogUtils.l("New EnableAction for client ", clientId, " : ", wordList); + DebugLogUtils.l("New EnableAction for client ", clientId, " : ", wordList); mClientId = clientId; mWordList = wordList; } @@ -243,7 +243,7 @@ public final class ActionBatch { Log.e(TAG, "EnableAction with a null parameter!"); return; } - LogUtils.l("Enabling word list"); + DebugLogUtils.l("Enabling word list"); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -267,7 +267,7 @@ public final class ActionBatch { // The word list to disable. May not be null. final WordListMetadata mWordList; public DisableAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New Disable action for client ", clientId, " : ", wordlist); + DebugLogUtils.l("New Disable action for client ", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -278,7 +278,7 @@ public final class ActionBatch { Log.e(TAG, "DisableAction with a null word list!"); return; } - LogUtils.l("Disabling word list : " + mWordList); + DebugLogUtils.l("Disabling word list : " + mWordList); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -314,7 +314,7 @@ public final class ActionBatch { // The word list to make available. May not be null. final WordListMetadata mWordList; public MakeAvailableAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New MakeAvailable action", clientId, " : ", wordlist); + DebugLogUtils.l("New MakeAvailable action", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -331,7 +331,7 @@ public final class ActionBatch { Log.e(TAG, "Unexpected state of the word list '" + mWordList.mId + "' " + " for a makeavailable action. Marking as available anyway."); } - LogUtils.l("Making word list available : " + mWordList); + DebugLogUtils.l("Making word list available : " + mWordList); // If mLocalFilename is null, then it's a remote file that hasn't been downloaded // yet, so we set the local filename to the empty string. final ContentValues values = MetadataDbHelper.makeContentValues(0, @@ -363,7 +363,7 @@ public final class ActionBatch { // The word list to mark pre-installed. May not be null. final WordListMetadata mWordList; public MarkPreInstalledAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New MarkPreInstalled action", clientId, " : ", wordlist); + DebugLogUtils.l("New MarkPreInstalled action", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -380,7 +380,7 @@ public final class ActionBatch { Log.e(TAG, "Unexpected state of the word list '" + mWordList.mId + "' " + " for a markpreinstalled action. Marking as preinstalled anyway."); } - LogUtils.l("Marking word list preinstalled : " + mWordList); + DebugLogUtils.l("Marking word list preinstalled : " + mWordList); // This word list is pre-installed : we don't have its file. We should reset // the local file name to the empty string so that we don't try to open it // accidentally. The remote filename may be set by the application if it so wishes. @@ -404,7 +404,7 @@ public final class ActionBatch { private final String mClientId; final WordListMetadata mWordList; public UpdateDataAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New UpdateData action for client ", clientId, " : ", wordlist); + DebugLogUtils.l("New UpdateData action for client ", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -422,7 +422,7 @@ public final class ActionBatch { Log.e(TAG, "Trying to update data about a non-existing word list. Bailing out."); return; } - LogUtils.l("Updating data about a word list : " + mWordList); + DebugLogUtils.l("Updating data about a word list : " + mWordList); final ContentValues values = MetadataDbHelper.makeContentValues( oldValues.getAsInteger(MetadataDbHelper.PENDINGID_COLUMN), oldValues.getAsInteger(MetadataDbHelper.TYPE_COLUMN), @@ -456,7 +456,7 @@ public final class ActionBatch { final boolean mHasNewerVersion; public ForgetAction(final String clientId, final WordListMetadata wordlist, final boolean hasNewerVersion) { - LogUtils.l("New TryRemove action for client ", clientId, " : ", wordlist); + DebugLogUtils.l("New TryRemove action for client ", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; mHasNewerVersion = hasNewerVersion; @@ -468,7 +468,7 @@ public final class ActionBatch { Log.e(TAG, "TryRemoveAction with a null word list!"); return; } - LogUtils.l("Trying to remove word list : " + mWordList); + DebugLogUtils.l("Trying to remove word list : " + mWordList); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -528,7 +528,7 @@ public final class ActionBatch { // The word list to delete. May not be null. final WordListMetadata mWordList; public StartDeleteAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New StartDelete action for client ", clientId, " : ", wordlist); + DebugLogUtils.l("New StartDelete action for client ", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -539,7 +539,7 @@ public final class ActionBatch { Log.e(TAG, "StartDeleteAction with a null word list!"); return; } - LogUtils.l("Trying to delete word list : " + mWordList); + DebugLogUtils.l("Trying to delete word list : " + mWordList); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -567,7 +567,7 @@ public final class ActionBatch { // The word list to delete. May not be null. final WordListMetadata mWordList; public FinishDeleteAction(final String clientId, final WordListMetadata wordlist) { - LogUtils.l("New FinishDelete action for client", clientId, " : ", wordlist); + DebugLogUtils.l("New FinishDelete action for client", clientId, " : ", wordlist); mClientId = clientId; mWordList = wordlist; } @@ -578,7 +578,7 @@ public final class ActionBatch { Log.e(TAG, "FinishDeleteAction with a null word list!"); return; } - LogUtils.l("Trying to delete word list : " + mWordList); + DebugLogUtils.l("Trying to delete word list : " + mWordList); final SQLiteDatabase db = MetadataDbHelper.getDb(context, mClientId); final ContentValues values = MetadataDbHelper.getContentValuesByWordListId(db, mWordList.mId, mWordList.mVersion); @@ -635,7 +635,7 @@ public final class ActionBatch { * @param reporter a Reporter to send errors to. */ public void execute(final Context context, final ProblemReporter reporter) { - LogUtils.l("Executing a batch of actions"); + DebugLogUtils.l("Executing a batch of actions"); Queue<Action> remainingActions = mActions; while (!remainingActions.isEmpty()) { final Action a = remainingActions.poll(); diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java index 4aa4d4b43..62b905dc5 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java @@ -31,7 +31,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import java.io.File; import java.io.FileNotFoundException; @@ -220,7 +220,7 @@ public final class DictionaryProvider extends ContentProvider { @Override public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) { - LogUtils.l("Uri =", uri); + DebugLogUtils.l("Uri =", uri); PrivateLog.log("Query : " + uri); final String clientId = getClientId(uri); final int match = matchUri(uri); @@ -228,7 +228,7 @@ public final class DictionaryProvider extends ContentProvider { case DICTIONARY_V1_WHOLE_LIST: case DICTIONARY_V2_WHOLE_LIST: final Cursor c = MetadataDbHelper.queryDictionaries(getContext(), clientId); - LogUtils.l("List of dictionaries with count", c.getCount()); + DebugLogUtils.l("List of dictionaries with count", c.getCount()); PrivateLog.log("Returned a list of " + c.getCount() + " items"); return c; case DICTIONARY_V2_DICT_INFO: diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java index c6cadb823..99cc5b924 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java @@ -25,7 +25,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import java.io.File; import java.util.ArrayList; @@ -773,13 +773,13 @@ public class MetadataDbHelper extends SQLiteOpenHelper { if (TextUtils.isEmpty(valuesClientId) || null == valuesMetadataUri || null == valuesMetadataAdditionalId) { // We need all these columns to be filled in - LogUtils.l("Missing parameter for updateClientInfo"); + DebugLogUtils.l("Missing parameter for updateClientInfo"); return; } if (!clientId.equals(valuesClientId)) { // Mismatch! The client violates the protocol. - LogUtils.l("Received an updateClientInfo request for ", clientId, " but the values " - + "contain a different ID : ", valuesClientId); + DebugLogUtils.l("Received an updateClientInfo request for ", clientId, + " but the values " + "contain a different ID : ", valuesClientId); return; } final SQLiteDatabase defaultDb = getDb(context, ""); @@ -848,7 +848,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { final ContentValues r) { switch (r.getAsInteger(TYPE_COLUMN)) { case TYPE_BULK: - LogUtils.l("Ended processing a wordlist"); + DebugLogUtils.l("Ended processing a wordlist"); // Updating a bulk word list is a three-step operation: // - Add the new entry to the table // - Remove the old entry from the table @@ -870,7 +870,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper { // the phone is suddenly cut during an update. final int filenameIndex = c.getColumnIndex(LOCAL_FILENAME_COLUMN); do { - LogUtils.l("Setting for removal", c.getString(filenameIndex)); + DebugLogUtils.l("Setting for removal", c.getString(filenameIndex)); filenames.add(c.getString(filenameIndex)); } while (c.moveToNext()); } diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java index 936d00d25..719f24e59 100644 --- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java @@ -38,7 +38,7 @@ import android.util.Log; import com.android.inputmethod.compat.ConnectivityManagerCompatUtils; import com.android.inputmethod.compat.DownloadManagerCompatUtils; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.Utils; import java.io.File; @@ -185,8 +185,8 @@ public final class UpdateHandler { final String clientId = cursor.getString(0); final String metadataUri = MetadataDbHelper.getMetadataUriAsString(context, clientId); - PrivateLog.log("Update for clientId " + LogUtils.s(clientId)); - LogUtils.l("Update for clientId", clientId, " which uses URI ", metadataUri); + PrivateLog.log("Update for clientId " + DebugLogUtils.s(clientId)); + DebugLogUtils.l("Update for clientId", clientId, " which uses URI ", metadataUri); uris.add(metadataUri); } while (cursor.moveToNext()); } finally { @@ -213,14 +213,14 @@ public final class UpdateHandler { */ private static void updateClientsWithMetadataUri(final Context context, final boolean updateNow, final String metadataUri) { - PrivateLog.log("Update for metadata URI " + LogUtils.s(metadataUri)); + PrivateLog.log("Update for metadata URI " + DebugLogUtils.s(metadataUri)); // Adding a disambiguator to circumvent a bug in older versions of DownloadManager. // DownloadManager also stupidly cuts the extension to replace with its own that it // gets from the content-type. We need to circumvent this. final String disambiguator = "#" + System.currentTimeMillis() + Utils.getVersionName(context) + ".json"; final Request metadataRequest = new Request(Uri.parse(metadataUri + disambiguator)); - LogUtils.l("Request =", metadataRequest); + DebugLogUtils.l("Request =", metadataRequest); final Resources res = context.getResources(); // By default, download over roaming is allowed and all network types are allowed too. @@ -256,7 +256,7 @@ public final class UpdateHandler { final long downloadId; synchronized (sSharedIdProtector) { downloadId = manager.enqueue(metadataRequest); - LogUtils.l("Metadata download requested with id", downloadId); + DebugLogUtils.l("Metadata download requested with id", downloadId); // If there is already a download in progress, it's been there for a while and // there is probably something wrong with download manager. It's best to just // overwrite the id and request it again. If the old one happens to finish @@ -328,11 +328,11 @@ public final class UpdateHandler { */ public static long registerDownloadRequest(final DownloadManager manager, final Request request, final SQLiteDatabase db, final String id, final int version) { - LogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version); + DebugLogUtils.l("RegisterDownloadRequest for word list id : ", id, ", version ", version); final long downloadId; synchronized (sSharedIdProtector) { downloadId = manager.enqueue(request); - LogUtils.l("Download requested with id", downloadId); + DebugLogUtils.l("Download requested with id", downloadId); MetadataDbHelper.markEntryAsDownloading(db, id, version, downloadId); } return downloadId; @@ -418,7 +418,7 @@ public final class UpdateHandler { // Get and check the ID of the file that was downloaded final long fileId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, NOT_AN_ID); PrivateLog.log("Download finished with id " + fileId); - LogUtils.l("DownloadFinished with id", fileId); + DebugLogUtils.l("DownloadFinished with id", fileId); if (NOT_AN_ID == fileId) return; // Spurious wake-up: ignore final DownloadManager manager = @@ -428,7 +428,7 @@ public final class UpdateHandler { final ArrayList<DownloadRecord> recordList = getDownloadRecordsForCompletedDownloadInfo(context, downloadInfo); if (null == recordList) return; // It was someone else's download. - LogUtils.l("Received result for download ", fileId); + DebugLogUtils.l("Received result for download ", fileId); // TODO: handle gracefully a null pointer here. This is practically impossible because // we come here only when DownloadManager explicitly called us when it ended a @@ -505,7 +505,7 @@ public final class UpdateHandler { private static void publishUpdateCycleCompletedEvent(final Context context) { // Even if this is not successful, we have to publish the new state. PrivateLog.log("Publishing update cycle completed event"); - LogUtils.l("Publishing update cycle completed event"); + DebugLogUtils.l("Publishing update cycle completed event"); for (UpdateEventListener listener : linkedCopyOfList(sUpdateEventListeners)) { listener.updateCycleCompleted(); } @@ -519,12 +519,12 @@ public final class UpdateHandler { // {@link handleWordList(Context,InputStream,ContentValues)}. // Handle the downloaded file according to its type if (downloadRecord.isMetadata()) { - LogUtils.l("Data D/L'd is metadata for", downloadRecord.mClientId); + DebugLogUtils.l("Data D/L'd is metadata for", downloadRecord.mClientId); // #handleMetadata() closes its InputStream argument handleMetadata(context, new ParcelFileDescriptor.AutoCloseInputStream( manager.openDownloadedFile(fileId)), downloadRecord.mClientId); } else { - LogUtils.l("Data D/L'd is a word list"); + DebugLogUtils.l("Data D/L'd is a word list"); final int wordListStatus = downloadRecord.mAttributes.getAsInteger( MetadataDbHelper.STATUS_COLUMN); if (MetadataDbHelper.STATUS_DOWNLOADING == wordListStatus) { @@ -584,7 +584,7 @@ public final class UpdateHandler { */ private static void handleMetadata(final Context context, final InputStream stream, final String clientId) throws IOException, BadFormatException { - LogUtils.l("Entering handleMetadata"); + DebugLogUtils.l("Entering handleMetadata"); final List<WordListMetadata> newMetadata; final InputStreamReader reader = new InputStreamReader(stream); try { @@ -594,7 +594,7 @@ public final class UpdateHandler { reader.close(); } - LogUtils.l("Downloaded metadata :", newMetadata); + DebugLogUtils.l("Downloaded metadata :", newMetadata); PrivateLog.log("Downloaded metadata\n" + newMetadata); final ActionBatch actions = computeUpgradeTo(context, clientId, newMetadata); @@ -619,7 +619,7 @@ public final class UpdateHandler { // DownloadManager does not have the ability to put the file directly where we want // it, so we had it download to a temporary place. Now we move it. It will be deleted // automatically by DownloadManager. - LogUtils.l("Downloaded a new word list :", downloadRecord.mAttributes.getAsString( + DebugLogUtils.l("Downloaded a new word list :", downloadRecord.mAttributes.getAsString( MetadataDbHelper.DESCRIPTION_COLUMN), "for", downloadRecord.mClientId); PrivateLog.log("Downloaded a new word list with description : " + downloadRecord.mAttributes.getAsString(MetadataDbHelper.DESCRIPTION_COLUMN) @@ -678,9 +678,9 @@ public final class UpdateHandler { */ private static void copyFile(final InputStream in, final OutputStream out) throws IOException { - LogUtils.l("Copying files"); + DebugLogUtils.l("Copying files"); if (!(in instanceof FileInputStream) || !(out instanceof FileOutputStream)) { - LogUtils.l("Not the right types"); + DebugLogUtils.l("Not the right types"); copyFileFallback(in, out); } else { try { @@ -689,7 +689,7 @@ public final class UpdateHandler { sourceChannel.transferTo(0, Integer.MAX_VALUE, destinationChannel); } catch (IOException e) { // Can't work with channels, or something went wrong. Copy by hand. - LogUtils.l("Won't work"); + DebugLogUtils.l("Won't work"); copyFileFallback(in, out); } } @@ -704,7 +704,7 @@ public final class UpdateHandler { */ private static void copyFileFallback(final InputStream in, final OutputStream out) throws IOException { - LogUtils.l("Falling back to slow copy"); + DebugLogUtils.l("Falling back to slow copy"); final byte[] buffer = new byte[FILE_COPY_BUFFER_SIZE]; for (int readBytes = in.read(buffer); readBytes >= 0; readBytes = in.read(buffer)) out.write(buffer, 0, readBytes); @@ -719,10 +719,10 @@ public final class UpdateHandler { */ private static String getTempFileName(final Context context, final String locale) throws IOException { - LogUtils.l("Entering openTempFileOutput"); + DebugLogUtils.l("Entering openTempFileOutput"); final File dir = context.getFilesDir(); final File f = File.createTempFile(locale + "___", DICT_FILE_SUFFIX, dir); - LogUtils.l("File name is", f.getName()); + DebugLogUtils.l("File name is", f.getName()); return f.getName(); } @@ -743,7 +743,7 @@ public final class UpdateHandler { final String clientId, List<WordListMetadata> from, List<WordListMetadata> to) { final ActionBatch actions = new ActionBatch(); // Upgrade existing word lists - LogUtils.l("Comparing dictionaries"); + DebugLogUtils.l("Comparing dictionaries"); final Set<String> wordListIds = new TreeSet<String>(); // TODO: Can these be null? if (null == from) from = new ArrayList<WordListMetadata>(); @@ -758,7 +758,7 @@ public final class UpdateHandler { final WordListMetadata newInfo = null == metadataInfo || metadataInfo.mFormatVersion > MAXIMUM_SUPPORTED_FORMAT_VERSION ? null : metadataInfo; - LogUtils.l("Considering updating ", id, "currentInfo =", currentInfo); + DebugLogUtils.l("Considering updating ", id, "currentInfo =", currentInfo); if (null == currentInfo && null == newInfo) { // This may happen if a new word list appeared that we can't handle. diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 05b1a2ee1..f36c9e878 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -78,20 +78,23 @@ public final class BinaryDictionary extends Dictionary { * @param length the length of the binary data. * @param useFullEditDistance whether to use the full edit distance in suggestions * @param dictType the dictionary type, as a human-readable string + * @param isUpdatable whether to open the dictionary file in writable mode. */ public BinaryDictionary(final String filename, final long offset, final long length, - final boolean useFullEditDistance, final Locale locale, final String dictType) { + final boolean useFullEditDistance, final Locale locale, final String dictType, + final boolean isUpdatable) { super(dictType); mLocale = locale; mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance); - loadDictionary(filename, offset, length); + loadDictionary(filename, offset, length, isUpdatable); } static { JniUtils.loadNativeLibrary(); } - private static native long openNative(String sourceDir, long dictOffset, long dictSize); + private static native long openNative(String sourceDir, long dictOffset, long dictSize, + boolean isUpdatable); private static native void closeNative(long dict); private static native int getProbabilityNative(long dict, int[] word); private static native boolean isValidBigramNative(long dict, int[] word1, int[] word2); @@ -105,8 +108,8 @@ public final class BinaryDictionary extends Dictionary { // TODO: Move native dict into session private final void loadDictionary(final String path, final long startOffset, - final long length) { - mNativeDict = openNative(path, startOffset, length); + final long length, final boolean isUpdatable) { + mNativeDict = openNative(path, startOffset, length, isUpdatable); } @Override diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 5b98613a4..3721132c5 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -60,7 +60,8 @@ public final class DictionaryFactory { if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename, - f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); + f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, + false /* isUpdatable */); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -113,7 +114,8 @@ public final class DictionaryFactory { return null; } return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), - false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); + false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN, + false /* isUpdatable */); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; @@ -142,7 +144,7 @@ public final class DictionaryFactory { for (final AssetFileAddress address : dictionaryList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, - Dictionary.TYPE_MAIN); + Dictionary.TYPE_MAIN, false /* isUpdatable */); dictionaryCollection.addDictionary(binaryDictionary); } return dictionaryCollection; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index f357e2a1e..9cdb86c2d 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -286,7 +286,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Build the new binary dictionary final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length, - true /* useFullEditDistance */, null, mDictType); + true /* useFullEditDistance */, null, mDictType, false /* isUpdatable */); if (mBinaryDictionary != null) { // Ensure all threads accessing the current dictionary have finished before swapping in diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 0efe0eba7..6fcac9a65 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -926,19 +926,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - // TODO: refactor the following code to be less contrived. - // "newSelStart != composingSpanEnd" || "newSelEnd != composingSpanEnd" means - // that the cursor is not at the end of the composing span, or there is a selection. - // "mLastSelectionStart != newSelStart" means that the cursor is not in the same place - // as last time we were called (if there is a selection, it means the start hasn't - // changed, so it's the end that did). - final boolean selectionChanged = (newSelStart != composingSpanEnd - || newSelEnd != composingSpanEnd) && mLastSelectionStart != newSelStart; + final boolean selectionChanged = mLastSelectionStart != newSelStart + || mLastSelectionEnd != newSelEnd; // if composingSpanStart and composingSpanEnd are -1, it means there is no composing // span in the view - we can use that to narrow down whether the cursor was moved // by us or not. If we are composing a word but there is no composing span, then // we know for sure the cursor moved while we were composing and we should reset - // the state. + // the state. TODO: rescind this policy: the framework never removes the composing + // span on its own accord while editing. This test is useless. + final boolean noComposingSpan = composingSpanStart == -1 && composingSpanEnd == -1; // If the keyboard is not visible, we don't need to do all the housekeeping work, as it // will be reset when the keyboard shows up anyway. @@ -979,6 +975,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (isSuggestionsStripVisible()) { mHandler.postResumeSuggestions(); } + mConnection.userMovedCursor(newSelEnd); // Reset the last recapitalization. mRecapitalizeStatus.deactivate(); mKeyboardSwitcher.updateShiftState(); @@ -2655,11 +2652,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - // Used by the RingCharBuffer - public boolean isWordSeparator(final int code) { - return mSettings.getCurrent().isWordSeparator(code); - } - // TODO: Make this private // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index d431ad60b..6e3e7b218 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -28,7 +28,7 @@ import android.view.inputmethod.InputConnection; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.utils.CapsModeUtils; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.research.ResearchLogger; @@ -107,7 +107,7 @@ public final class RichInputConnection { + "\nActual text = " + reference.length() + " " + reference; ((LatinIME)mParent).debugDumpStateAndCrashWithException(context); } else { - Log.e(TAG, LogUtils.getStackTrace(2)); + Log.e(TAG, DebugLogUtils.getStackTrace(2)); Log.e(TAG, "Exp <> Actual : " + mCurrentCursorPosition + " <> " + et.selectionStart); } } @@ -156,7 +156,7 @@ public final class RichInputConnection { if (mNestLevel != 1) { // TODO: exception instead Log.e(TAG, "Batch edit level incorrect : " + mNestLevel); - Log.e(TAG, LogUtils.getStackTrace(4)); + Log.e(TAG, DebugLogUtils.getStackTrace(4)); } } @@ -340,7 +340,6 @@ public final class RichInputConnection { public void setComposingRegion(final int start, final int end) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); - mCurrentCursorPosition = end; final CharSequence textBeforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE + (end - start), 0); mCommittedTextBeforeComposingText.setLength(0); @@ -731,6 +730,14 @@ public final class RichInputConnection { } /** + * The user moved the cursor by hand. Take a note of it. + * @param newCursorPosition The new cursor position. + */ + public void userMovedCursor(final int newCursorPosition) { + mCurrentCursorPosition = newCursorPosition; + } + + /** * Looks at the text just before the cursor to find out if it looks like a URL. * * The weakest point here is, if we don't have enough text bufferized, we may fail to realize diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 084d3308c..adc92d021 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -152,6 +152,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return mSettingsValues.mWordSeparators; } + public boolean isWordSeparator(final int code) { + return mSettingsValues.isWordSeparator(code); + } + public Locale getCurrentLocale() { return mCurrentLocale; } diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index 3f94aca3a..30df2eb4e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -26,9 +26,9 @@ import android.util.Log; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; -import com.android.inputmethod.latin.utils.LogUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.HashMap; @@ -242,7 +242,7 @@ public final class SubtypeLocale { + " nameResId=" + subtype.getNameResId() + " locale=" + subtype.getLocale() + " extra=" + subtype.getExtraValue() - + "\n" + LogUtils.getStackTrace()); + + "\n" + DebugLogUtils.getStackTrace()); return ""; } } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index b6caf9b7b..9565f63f7 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -86,6 +86,7 @@ final class SuggestionStripLayoutHelper { private final float mAlphaObsoleted; private final float mCenterSuggestionWeight; private final int mCenterPositionInStrip; + private final int mTypedWordPositionWhenAutocorrect; private final Drawable mMoreSuggestionsHint; private static final String MORE_SUGGESTIONS_HINT = "\u2026"; private static final String LEFTWARDS_ARROW = "\u2190"; @@ -159,6 +160,10 @@ final class SuggestionStripLayoutHelper { mMoreSuggestionsHint = getMoreSuggestionsHint(res, res.getDimension(R.dimen.more_suggestions_hint_text_size), mColorAutoCorrect); mCenterPositionInStrip = mSuggestionsCountInStrip / 2; + // Assuming there are at least three suggestions. Also, note that the suggestions are + // laid out according to script direction, so this is left of the center for LTR scripts + // and right of the center for RTL scripts. + mTypedWordPositionWhenAutocorrect = mCenterPositionInStrip - 1; mMoreSuggestionsBottomGap = res.getDimensionPixelOffset( R.dimen.more_suggestions_bottom_gap); mMoreSuggestionsRowHeight = res.getDimensionPixelSize(R.dimen.more_suggestions_row_height); @@ -233,24 +238,31 @@ final class SuggestionStripLayoutHelper { return spannedWord; } - private int getIndexInSuggestedWords(final int positionInStrip, + private int getPositionInSuggestionStrip(final int indexInSuggestedWords, final SuggestedWords suggestedWords) { - // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more - // suggestions. - final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() - ? SuggestedWords.INDEX_OF_AUTO_CORRECTION : SuggestedWords.INDEX_OF_TYPED_WORD; - if (positionInStrip == mCenterPositionInStrip) { - return mostImportantIndexInSuggestedWords; + final int indexToDisplayMostImportantSuggestion; + final int indexToDisplaySecondMostImportantSuggestion; + if (suggestedWords.willAutoCorrect()) { + indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION; + indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD; + } else { + indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD; + indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION; } - if (positionInStrip == mostImportantIndexInSuggestedWords) { + if (indexInSuggestedWords == indexToDisplayMostImportantSuggestion) { return mCenterPositionInStrip; } - return positionInStrip; + if (indexInSuggestedWords == indexToDisplaySecondMostImportantSuggestion) { + return mTypedWordPositionWhenAutocorrect; + } + // If neither of those, the order in the suggestion strip is the same as in SuggestedWords. + return indexInSuggestedWords; } - private int getSuggestionTextColor(final int positionInStrip, + private int getSuggestionTextColor(final int indexInSuggestedWords, final SuggestedWords suggestedWords) { - final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords); + final int positionInStrip = + getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords); // TODO: Need to revisit this logic with bigram suggestions final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD); @@ -352,7 +364,7 @@ final class SuggestionStripLayoutHelper { * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0. * The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This * usually doesn't match the index in <code>suggedtedWords</code> -- see - * {@link #getIndexInSuggestedWords(int,SuggestedWords)}. + * {@link #getPositionInSuggestionStrip(int,SuggestedWords)}. * * @param positionInStrip the position in the suggestion strip. * @param width the maximum width for layout in pixels. @@ -413,10 +425,19 @@ final class SuggestionStripLayoutHelper { private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords, final int countInStrip) { + // Clear all suggestions first + for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) { + mWordViews.get(positionInStrip).setText(null); + // Make this inactive for touches in {@link #layoutWord(int,int)}. + if (SuggestionStripView.DBG) { + mDebugInfoViews.get(positionInStrip).setText(null); + } + } final int count = Math.min(suggestedWords.size(), countInStrip); - for (int positionInStrip = 0; positionInStrip < count; positionInStrip++) { - final int indexInSuggestedWords = - getIndexInSuggestedWords(positionInStrip, suggestedWords); + for (int indexInSuggestedWords = 0; indexInSuggestedWords < count; + indexInSuggestedWords++) { + final int positionInStrip = + getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords); final TextView wordView = mWordViews.get(positionInStrip); // {@link TextView#getTag()} is used to get the index in suggestedWords at // {@link SuggestionStripView#onClick(View)}. @@ -428,13 +449,6 @@ final class SuggestionStripLayoutHelper { Utils.getDebugInfo(suggestedWords, indexInSuggestedWords)); } } - for (int positionInStrip = count; positionInStrip < countInStrip; positionInStrip++) { - mWordViews.get(positionInStrip).setText(null); - // Make this inactive for touches in {@link #layoutWord(int,int)}. - if (SuggestionStripView.DBG) { - mDebugInfoViews.get(positionInStrip).setText(null); - } - } } private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords, diff --git a/java/src/com/android/inputmethod/latin/utils/LogUtils.java b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java index a0d2e0495..c4ead0ad1 100644 --- a/java/src/com/android/inputmethod/latin/utils/LogUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java @@ -23,8 +23,8 @@ import com.android.inputmethod.latin.LatinImeLogger; /** * A class for logging and debugging utility methods. */ -public final class LogUtils { - private final static String TAG = LogUtils.class.getSimpleName(); +public final class DebugLogUtils { + private final static String TAG = DebugLogUtils.class.getSimpleName(); private final static boolean sDBG = LatinImeLogger.sDBG; /** diff --git a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java new file mode 100644 index 000000000..3e67e8216 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java @@ -0,0 +1,134 @@ +/* + * 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.utils; + +import android.inputmethodservice.InputMethodService; + +import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.utils.Utils.UsabilityStudyLogUtils; + +public final class UserLogRingCharBuffer { + public /* for test */ static final int BUFSIZE = 20; + public /* for test */ int mLength = 0; + + private static UserLogRingCharBuffer sUserLogRingCharBuffer = new UserLogRingCharBuffer(); + private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; + private static final int INVALID_COORDINATE = -2; + private boolean mEnabled = false; + private int mEnd = 0; + private char[] mCharBuf = new char[BUFSIZE]; + private int[] mXBuf = new int[BUFSIZE]; + private int[] mYBuf = new int[BUFSIZE]; + + private UserLogRingCharBuffer() { + // Intentional empty constructor for singleton. + } + + @UsedForTesting + public static UserLogRingCharBuffer getInstance() { + return sUserLogRingCharBuffer; + } + + public static UserLogRingCharBuffer init(final InputMethodService context, + final boolean enabled, final boolean usabilityStudy) { + if (!(enabled || usabilityStudy)) { + return null; + } + sUserLogRingCharBuffer.mEnabled = true; + UsabilityStudyLogUtils.getInstance().init(context); + return sUserLogRingCharBuffer; + } + + private static int normalize(final int in) { + int ret = in % BUFSIZE; + return ret < 0 ? ret + BUFSIZE : ret; + } + + // TODO: accept code points + @UsedForTesting + public void push(final char c, final int x, final int y) { + if (!mEnabled) { + return; + } + mCharBuf[mEnd] = c; + mXBuf[mEnd] = x; + mYBuf[mEnd] = y; + mEnd = normalize(mEnd + 1); + if (mLength < BUFSIZE) { + ++mLength; + } + } + + public char pop() { + if (mLength < 1) { + return PLACEHOLDER_DELIMITER_CHAR; + } + mEnd = normalize(mEnd - 1); + --mLength; + return mCharBuf[mEnd]; + } + + public char getBackwardNthChar(final int n) { + if (mLength <= n || n < 0) { + return PLACEHOLDER_DELIMITER_CHAR; + } + return mCharBuf[normalize(mEnd - n - 1)]; + } + + public int getPreviousX(final char c, final int back) { + final int index = normalize(mEnd - 2 - back); + if (mLength <= back + || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { + return INVALID_COORDINATE; + } + return mXBuf[index]; + } + + public int getPreviousY(final char c, final int back) { + int index = normalize(mEnd - 2 - back); + if (mLength <= back + || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { + return INVALID_COORDINATE; + } + return mYBuf[index]; + } + + public String getLastWord(final int ignoreCharCount) { + final StringBuilder sb = new StringBuilder(); + int i = ignoreCharCount; + for (; i < mLength; ++i) { + final char c = mCharBuf[normalize(mEnd - 1 - i)]; + if (!Settings.getInstance().isWordSeparator(c)) { + break; + } + } + for (; i < mLength; ++i) { + char c = mCharBuf[normalize(mEnd - 1 - i)]; + if (!Settings.getInstance().isWordSeparator(c)) { + sb.append(c); + } else { + break; + } + } + return sb.reverse().toString(); + } + + public void reset() { + mLength = 0; + } +} diff --git a/java/src/com/android/inputmethod/latin/utils/Utils.java b/java/src/com/android/inputmethod/latin/utils/Utils.java index 390d306c8..c4e18ed7e 100644 --- a/java/src/com/android/inputmethod/latin/utils/Utils.java +++ b/java/src/com/android/inputmethod/latin/utils/Utils.java @@ -26,7 +26,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.inputmethodservice.InputMethodService; import android.net.Uri; -import android.os.AsyncTask; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -34,9 +33,7 @@ import android.os.Process; import android.text.TextUtils; import android.util.Log; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -63,135 +60,6 @@ public final class Utils { // This utility class is not publicly instantiable. } - /** - * Cancel an {@link AsyncTask}. - * - * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this - * task should be interrupted; otherwise, in-progress tasks are allowed - * to complete. - */ - public static void cancelTask(final AsyncTask<?, ?, ?> task, - final boolean mayInterruptIfRunning) { - if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) { - task.cancel(mayInterruptIfRunning); - } - } - - // TODO: Make this an external class - public /* for test */ static final class RingCharBuffer { - public /* for test */ static final int BUFSIZE = 20; - public /* for test */ int mLength = 0; - - private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); - private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; - private static final int INVALID_COORDINATE = -2; - private InputMethodService mContext; - private boolean mEnabled = false; - private int mEnd = 0; - private char[] mCharBuf = new char[BUFSIZE]; - private int[] mXBuf = new int[BUFSIZE]; - private int[] mYBuf = new int[BUFSIZE]; - - private RingCharBuffer() { - // Intentional empty constructor for singleton. - } - - @UsedForTesting - public static RingCharBuffer getInstance() { - return sRingCharBuffer; - } - - public static RingCharBuffer init(final InputMethodService context, final boolean enabled, - final boolean usabilityStudy) { - if (!(enabled || usabilityStudy)) { - return null; - } - sRingCharBuffer.mContext = context; - sRingCharBuffer.mEnabled = true; - UsabilityStudyLogUtils.getInstance().init(context); - return sRingCharBuffer; - } - - private static int normalize(final int in) { - int ret = in % BUFSIZE; - return ret < 0 ? ret + BUFSIZE : ret; - } - - // TODO: accept code points - @UsedForTesting - public void push(final char c, final int x, final int y) { - if (!mEnabled) { - return; - } - mCharBuf[mEnd] = c; - mXBuf[mEnd] = x; - mYBuf[mEnd] = y; - mEnd = normalize(mEnd + 1); - if (mLength < BUFSIZE) { - ++mLength; - } - } - - public char pop() { - if (mLength < 1) { - return PLACEHOLDER_DELIMITER_CHAR; - } - mEnd = normalize(mEnd - 1); - --mLength; - return mCharBuf[mEnd]; - } - - public char getBackwardNthChar(final int n) { - if (mLength <= n || n < 0) { - return PLACEHOLDER_DELIMITER_CHAR; - } - return mCharBuf[normalize(mEnd - n - 1)]; - } - - public int getPreviousX(final char c, final int back) { - final int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } - return mXBuf[index]; - } - - public int getPreviousY(final char c, final int back) { - int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } - return mYBuf[index]; - } - - public String getLastWord(final int ignoreCharCount) { - final StringBuilder sb = new StringBuilder(); - final LatinIME latinIme = (LatinIME)mContext; - int i = ignoreCharCount; - for (; i < mLength; ++i) { - final char c = mCharBuf[normalize(mEnd - 1 - i)]; - if (!latinIme.isWordSeparator(c)) { - break; - } - } - for (; i < mLength; ++i) { - char c = mCharBuf[normalize(mEnd - 1 - i)]; - if (!latinIme.isWordSeparator(c)) { - sb.append(c); - } else { - break; - } - } - return sb.reverse().toString(); - } - - public void reset() { - mLength = 0; - } - } - // TODO: Make this an external class public static final class UsabilityStudyLogUtils { // TODO: remove code duplication with ResearchLog class @@ -409,7 +277,7 @@ public final class Utils { // TODO: Make this an external class public static final class Stats { public static void onNonSeparator(final char code, final int x, final int y) { - RingCharBuffer.getInstance().push(code, x, y); + UserLogRingCharBuffer.getInstance().push(code, x, y); LatinImeLogger.logOnInputChar(); } @@ -424,7 +292,7 @@ public final class Utils { for (int i = 0; i < length; i = Character.offsetByCodePoints(separator, i, 1)) { int codePoint = Character.codePointAt(separator, i); // TODO: accept code points - RingCharBuffer.getInstance().push((char)codePoint, x, y); + UserLogRingCharBuffer.getInstance().push((char)codePoint, x, y); } LatinImeLogger.logOnInputSeparator(); } |