ResearchLogger.java revision c8e45ddb032554f4e9d4411d8ef47d98db62d77b
1d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge/* 2d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Copyright (C) 2012 The Android Open Source Project 3d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 4d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * use this file except in compliance with the License. You may obtain a copy of 6d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * the License at 7d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 8d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * http://www.apache.org/licenses/LICENSE-2.0 9d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 10d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Unless required by applicable law or agreed to in writing, software 11d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * License for the specific language governing permissions and limitations under 14d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * the License. 15d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge */ 16d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 176b966160ac8570271547bf63217efa5e228d4accKurt Partridgepackage com.android.inputmethod.research; 18d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 1986fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridgeimport static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; 2086fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge 21724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.app.AlertDialog; 224331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.app.Dialog; 2373c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.Context; 24724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.content.DialogInterface; 254331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.content.DialogInterface.OnCancelListener; 26d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.content.SharedPreferences; 2777814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport android.content.SharedPreferences.Editor; 2873c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.pm.PackageInfo; 2973c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.pm.PackageManager.NameNotFoundException; 304fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Canvas; 314fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Color; 324fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Paint; 334fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Paint.Style; 34c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaokaimport android.inputmethodservice.InputMethodService; 3548a7681e064ae259b840f0e757da2d716043d893Kurt Partridgeimport android.os.Build; 364331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.os.IBinder; 37d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.text.TextUtils; 3881dae8d015f63834b2ded44424636b625ece7736Kurt Partridgeimport android.text.format.DateUtils; 39d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.util.Log; 40d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.view.MotionEvent; 414331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.View; 424331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.View.OnClickListener; 434331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.Window; 444331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.WindowManager; 459bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.CompletionInfo; 469bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.EditorInfo; 47d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridgeimport android.view.inputmethod.InputConnection; 484331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.widget.Button; 49724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.widget.Toast; 50d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 519bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.keyboard.Key; 52d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport com.android.inputmethod.keyboard.Keyboard; 5386fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridgeimport com.android.inputmethod.keyboard.KeyboardId; 54223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridgeimport com.android.inputmethod.keyboard.KeyboardSwitcher; 554fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport com.android.inputmethod.keyboard.KeyboardView; 56c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaokaimport com.android.inputmethod.keyboard.MainKeyboardView; 576b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.Dictionary; 586b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.LatinIME; 596b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.R; 606b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.RichInputConnection; 6165fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridgeimport com.android.inputmethod.latin.RichInputConnection.Range; 626b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.Suggest; 636b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.SuggestedWords; 649bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.latin.define.ProductionFlag; 65d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 66d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport java.io.File; 67b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridgeimport java.io.IOException; 6807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.text.SimpleDateFormat; 696080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridgeimport java.util.ArrayList; 7007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Date; 716080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridgeimport java.util.List; 7207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Locale; 7377814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport java.util.UUID; 74d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 75d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge/** 76d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Logs the use of the LatinIME keyboard. 77d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 78d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * This class logs operations on the IME keyboard, including what the user has typed. 79d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Data is stored locally in a file in app-specific storage. 80d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 8193ebf74bae44728e0d5f7e738ea28376187a876eTadashi G. Takaoka * This functionality is off by default. See {@link ProductionFlag#IS_EXPERIMENTAL}. 82d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge */ 83d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgepublic class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener { 84d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge private static final String TAG = ResearchLogger.class.getSimpleName(); 856080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private static final boolean OUTPUT_ENTIRE_BUFFER = false; // true may disclose private info 866b966160ac8570271547bf63217efa5e228d4accKurt Partridge public static final boolean DEFAULT_USABILITY_STUDY_MODE = false; 8707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge /* package */ static boolean sIsLogging = false; 8858caa775a700e99d18cdca922861f1882bf8d1f4Kurt Partridge private static final int OUTPUT_FORMAT_VERSION = 1; 8907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; 904331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private static final String PREF_RESEARCH_HAS_SEEN_SPLASH = "pref_research_has_seen_splash"; 910df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge /* package */ static final String FILENAME_PREFIX = "researchLog"; 9207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String FILENAME_SUFFIX = ".txt"; 9307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final SimpleDateFormat TIMESTAMP_DATEFORMAT = 94223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge new SimpleDateFormat("yyyyMMddHHmmssS", Locale.US); 954fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge private static final boolean IS_SHOWING_INDICATOR = true; 964fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge private static final boolean IS_SHOWING_INDICATOR_CLEARLY = false; 9707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 9807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // constants related to specific log points 99aec44d50a7534d8704a7006b4f90f5e8040a931bKurt Partridge private static final String WHITESPACE_SEPARATORS = " \t\n\r"; 100d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1 10107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String PREF_RESEARCH_LOGGER_UUID_STRING = "pref_research_logger_uuid"; 1023c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private static final int ABORT_TIMEOUT_IN_MS = 10 * 1000; // timeout to notify user 103d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 10407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final ResearchLogger sInstance = new ResearchLogger(); 10507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // to write to a different filename, e.g., for testing, set mFile before calling start() 106223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ File mFilesDir; 107223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ String mUUIDString; 108223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ ResearchLog mMainResearchLog; 109223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // The mIntentionalResearchLog records all events for the session, private or not (excepting 110223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // passwords). It is written to permanent storage only if the user explicitly commands 111223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // the system to do so. 112223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ ResearchLog mIntentionalResearchLog; 113223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // LogUnits are queued here and released only when the user requests the intentional log. 1143c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private List<LogUnit> mIntentionalResearchLogQueue = new ArrayList<LogUnit>(); 115223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 1161cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private boolean mIsPasswordView = false; 117223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private boolean mIsLoggingSuspended = false; 1180df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private SharedPreferences mPrefs; 119d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 120a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge // digits entered by the user are replaced with this codepoint. 121a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge /* package for test */ static final int DIGIT_REPLACEMENT_CODEPOINT = 122a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area" 1236080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // U+E001 is in the "private-use area" 1246080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge /* package for test */ static final String WORD_REPLACEMENT_STRING = "\uE001"; 12581dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final String PREF_LAST_CLEANUP_TIME = "pref_last_cleanup_time"; 12681dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final long DURATION_BETWEEN_DIR_CLEANUP_IN_MS = DateUtils.DAY_IN_MILLIS; 12781dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final long MAX_LOGFILE_AGE_IN_MS = DateUtils.DAY_IN_MILLIS; 1280df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge protected static final int SUSPEND_DURATION_IN_MINUTES = 1; 12907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // set when LatinIME should ignore an onUpdateSelection() callback that 13007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // arises from operations in this class 13107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static boolean sLatinIMEExpectingUpdateSelection = false; 132d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 1336080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // used to check whether words are not unique 1346080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private Suggest mSuggest; 1356080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private Dictionary mDictionary; 136223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private KeyboardSwitcher mKeyboardSwitcher; 1374331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private InputMethodService mInputMethodService; 138b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge 1399c539d5a5c8e9b36be482fd7ebb2a71a22ef6af0Kurt Partridge private ResearchLogUploader mResearchLogUploader; 1409c539d5a5c8e9b36be482fd7ebb2a71a22ef6af0Kurt Partridge 14107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private ResearchLogger() { 14207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 143d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 14407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static ResearchLogger getInstance() { 14507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge return sInstance; 14607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 147d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 148223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public void init(final InputMethodService ims, final SharedPreferences prefs, 149223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge KeyboardSwitcher keyboardSwitcher) { 15007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge assert ims != null; 15107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (ims == null) { 15207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IMS is null; logging is off"); 15307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } else { 15407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge mFilesDir = ims.getFilesDir(); 15507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (mFilesDir == null || !mFilesDir.exists()) { 15607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IME storage directory does not exist."); 157d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 158d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 15907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (prefs != null) { 160223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mUUIDString = getUUID(prefs); 1610df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!prefs.contains(PREF_USABILITY_STUDY_MODE)) { 1620df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Editor e = prefs.edit(); 1630df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.putBoolean(PREF_USABILITY_STUDY_MODE, DEFAULT_USABILITY_STUDY_MODE); 1640df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.apply(); 1650df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 16607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); 167724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge prefs.registerOnSharedPreferenceChangeListener(this); 16881dae8d015f63834b2ded44424636b625ece7736Kurt Partridge 16981dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long lastCleanupTime = prefs.getLong(PREF_LAST_CLEANUP_TIME, 0L); 17081dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long now = System.currentTimeMillis(); 17181dae8d015f63834b2ded44424636b625ece7736Kurt Partridge if (lastCleanupTime + DURATION_BETWEEN_DIR_CLEANUP_IN_MS < now) { 17281dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long timeHorizon = now - MAX_LOGFILE_AGE_IN_MS; 17381dae8d015f63834b2ded44424636b625ece7736Kurt Partridge cleanupLoggingDir(mFilesDir, timeHorizon); 17481dae8d015f63834b2ded44424636b625ece7736Kurt Partridge Editor e = prefs.edit(); 17581dae8d015f63834b2ded44424636b625ece7736Kurt Partridge e.putLong(PREF_LAST_CLEANUP_TIME, now); 17681dae8d015f63834b2ded44424636b625ece7736Kurt Partridge e.apply(); 17781dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 178d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 1799c539d5a5c8e9b36be482fd7ebb2a71a22ef6af0Kurt Partridge mResearchLogUploader = new ResearchLogUploader(ims, mFilesDir); 1809c539d5a5c8e9b36be482fd7ebb2a71a22ef6af0Kurt Partridge mResearchLogUploader.start(); 181223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mKeyboardSwitcher = keyboardSwitcher; 1824331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mInputMethodService = ims; 1830df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mPrefs = prefs; 184223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 185223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 18681dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private void cleanupLoggingDir(final File dir, final long time) { 18781dae8d015f63834b2ded44424636b625ece7736Kurt Partridge for (File file : dir.listFiles()) { 18881dae8d015f63834b2ded44424636b625ece7736Kurt Partridge if (file.getName().startsWith(ResearchLogger.FILENAME_PREFIX) && 18981dae8d015f63834b2ded44424636b625ece7736Kurt Partridge file.lastModified() < time) { 19081dae8d015f63834b2ded44424636b625ece7736Kurt Partridge file.delete(); 19181dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 19281dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 19381dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 19481dae8d015f63834b2ded44424636b625ece7736Kurt Partridge 195c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public void mainKeyboardView_onAttachedToWindow() { 1964331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge maybeShowSplashScreen(); 1974331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 1984331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 1994331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private boolean hasSeenSplash() { 2004331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return mPrefs.getBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, false); 2014331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2024331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 2034331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private Dialog mSplashDialog = null; 2044331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 2054331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private void maybeShowSplashScreen() { 2064331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (hasSeenSplash()) { 2074331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2084331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2094331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (mSplashDialog != null && mSplashDialog.isShowing()) { 2104331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2114331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2124331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final IBinder windowToken = mKeyboardSwitcher.getKeyboardView().getWindowToken(); 2134331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (windowToken == null) { 2144331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2154331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2164331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog = new Dialog(mInputMethodService, android.R.style.Theme_Holo_Dialog); 2174331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 2184331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.setContentView(R.layout.research_splash); 2194331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.setCancelable(true); 2204331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Window w = mSplashDialog.getWindow(); 2214331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final WindowManager.LayoutParams lp = w.getAttributes(); 2224331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge lp.token = windowToken; 2234331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2244331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge w.setAttributes(lp); 2254331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge w.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2264331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.setOnCancelListener(new OnCancelListener() { 2274331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge @Override 2284331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge public void onCancel(DialogInterface dialog) { 2294331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mInputMethodService.requestHideSelf(0); 2304331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2314331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge }); 2324331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Button doNotLogButton = (Button) mSplashDialog.findViewById( 2334331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge R.id.research_do_not_log_button); 2344331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge doNotLogButton.setOnClickListener(new OnClickListener() { 2354331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge @Override 2364331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge public void onClick(View v) { 2374331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge onUserLoggingElection(false); 2384331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.dismiss(); 2394331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2404331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge }); 2414331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Button doLogButton = (Button) mSplashDialog.findViewById(R.id.research_do_log_button); 2424331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge doLogButton.setOnClickListener(new OnClickListener() { 2434331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge @Override 2444331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge public void onClick(View v) { 2454331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge onUserLoggingElection(true); 2464331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.dismiss(); 2474331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2484331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge }); 2494331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.show(); 2504331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2514331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 2524331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge public void onUserLoggingElection(final boolean enableLogging) { 2534331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge setLoggingAllowed(enableLogging); 2544331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (mPrefs == null) { 2554331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2564331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2574331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Editor e = mPrefs.edit(); 2584331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge e.putBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, true); 2594331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge e.apply(); 2604331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2614331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 262223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private File createLogFile(File filesDir) { 263223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge final StringBuilder sb = new StringBuilder(); 264223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(FILENAME_PREFIX).append('-'); 265223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(mUUIDString).append('-'); 266223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(TIMESTAMP_DATEFORMAT.format(new Date())); 267223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(FILENAME_SUFFIX); 268223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge return new File(filesDir, sb.toString()); 26907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 270b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge 2710df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void start() { 2724331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge maybeShowSplashScreen(); 2730df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge updateSuspendedState(); 2740df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 2750df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!isAllowedToLog()) { 276724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge // Log.w(TAG, "not in usability mode; not logging"); 277724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge return; 278724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 27907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (mFilesDir == null || !mFilesDir.exists()) { 28007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IME storage directory does not exist. Cannot start logging."); 281223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge return; 282223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 283223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge try { 2840df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (mMainResearchLog == null || !mMainResearchLog.isAlive()) { 2850df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mMainResearchLog = new ResearchLog(createLogFile(mFilesDir)); 2860df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 287223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.start(); 288223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mIntentionalResearchLog == null || !mIntentionalResearchLog.isAlive()) { 289223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mIntentionalResearchLog = new ResearchLog(createLogFile(mFilesDir)); 290b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge } 291223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mIntentionalResearchLog.start(); 292223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } catch (IOException e) { 293223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge Log.w(TAG, "Could not start ResearchLogger."); 294b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge } 295d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 296d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 2970df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge /* package */ void stop() { 298223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mMainResearchLog != null) { 299223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.stop(); 300223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 3010df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (mIntentionalResearchLog != null) { 3020df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIntentionalResearchLog.stop(); 3030df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3040df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3050df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 3060df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void setLoggingAllowed(boolean enableLogging) { 3070df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (mPrefs == null) { 3080df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return; 3090df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3100df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Editor e = mPrefs.edit(); 3110df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.putBoolean(PREF_USABILITY_STUDY_MODE, enableLogging); 3120df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.apply(); 3130df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge sIsLogging = enableLogging; 314223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 315223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 316223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public boolean abort() { 317223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge boolean didAbortMainLog = false; 318223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mMainResearchLog != null) { 319223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.abort(); 32048a7681e064ae259b840f0e757da2d716043d893Kurt Partridge try { 321223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.waitUntilStopped(ABORT_TIMEOUT_IN_MS); 32207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } catch (InterruptedException e) { 323223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // interrupted early. carry on. 324223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 325223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mMainResearchLog.isAbortSuccessful()) { 326223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge didAbortMainLog = true; 32748a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 3280df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mMainResearchLog = null; 329d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 330223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge boolean didAbortIntentionalLog = false; 331223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mIntentionalResearchLog != null) { 332223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mIntentionalResearchLog.abort(); 333724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge try { 334223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mIntentionalResearchLog.waitUntilStopped(ABORT_TIMEOUT_IN_MS); 335223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } catch (InterruptedException e) { 336223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // interrupted early. carry on. 337223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 338223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mIntentionalResearchLog.isAbortSuccessful()) { 339223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge didAbortIntentionalLog = true; 340724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 3410df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIntentionalResearchLog = null; 342724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 343223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge return didAbortMainLog && didAbortIntentionalLog; 344724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 345724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge 346223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ void flush() { 347223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (mMainResearchLog != null) { 348223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.flush(); 349223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 350223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 351223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 3520df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void restart() { 3530df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge stop(); 3540df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge start(); 3550df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3560df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 3570df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private long mResumeTime = 0L; 3580df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void suspendLoggingUntil(long time) { 3590df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIsLoggingSuspended = true; 3600df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mResumeTime = time; 3610df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 3620df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3630df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 3640df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void resumeLogging() { 3650df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mResumeTime = 0L; 3660df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge updateSuspendedState(); 3670df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 3680df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (isAllowedToLog()) { 3690df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge restart(); 3700df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3710df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3720df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 3730df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void updateSuspendedState() { 3740df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final long time = System.currentTimeMillis(); 3750df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (time > mResumeTime) { 3760df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIsLoggingSuspended = false; 3770df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3780df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 3790df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 38007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge @Override 38107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 38207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key == null || prefs == null) { 38307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge return; 384d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 38507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); 386724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge if (sIsLogging == false) { 387724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge abort(); 388724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 3890df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 390724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 391724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge 3926b966160ac8570271547bf63217efa5e228d4accKurt Partridge public void presentResearchDialog(final LatinIME latinIME) { 3933c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge if (mInFeedbackDialog) { 3943c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.makeText(latinIME, R.string.research_please_exit_feedback_form, 3953c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.LENGTH_LONG).show(); 3963c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge return; 3973c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 398724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final CharSequence title = latinIME.getString(R.string.english_ime_research_log); 3990df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final boolean showEnable = mIsLoggingSuspended || !sIsLogging; 400724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final CharSequence[] items = new CharSequence[] { 4013c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.getString(R.string.research_feedback_menu_option), 4023c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge showEnable ? latinIME.getString(R.string.research_enable_session_logging) : 4033c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.getString(R.string.research_do_not_log_this_session) 404724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 405724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 406724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge @Override 407724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge public void onClick(DialogInterface di, int position) { 408724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge di.dismiss(); 409724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge switch (position) { 410724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge case 0: 4113c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge presentFeedbackDialog(latinIME); 412724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge break; 413724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge case 1: 4140df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (showEnable) { 4150df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!sIsLogging) { 4160df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge setLoggingAllowed(true); 4170df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4180df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge resumeLogging(); 4193c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.makeText(latinIME, 4203c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge R.string.research_notify_session_logging_enabled, 4210df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Toast.LENGTH_LONG).show(); 422724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } else { 423223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge Toast toast = Toast.makeText(latinIME, 4243c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge R.string.research_notify_session_log_deleting, 4253c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.LENGTH_LONG); 426223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge toast.show(); 427223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge boolean isLogDeleted = abort(); 4280df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final long currentTime = System.currentTimeMillis(); 4290df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final long resumeTime = currentTime + 1000 * 60 * 4300df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge SUSPEND_DURATION_IN_MINUTES; 4310df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge suspendLoggingUntil(resumeTime); 432223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge toast.cancel(); 4333c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.makeText(latinIME, R.string.research_notify_logging_suspended, 4340df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Toast.LENGTH_LONG).show(); 435223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 436223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge break; 437724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 438724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 439223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 440724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 441724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final AlertDialog.Builder builder = new AlertDialog.Builder(latinIME) 442724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge .setItems(items, listener) 443724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge .setTitle(title); 444724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge latinIME.showOptionDialog(builder.create()); 445d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 446d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 4473c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private boolean mInFeedbackDialog = false; 4483c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void presentFeedbackDialog(LatinIME latinIME) { 4493c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mInFeedbackDialog = true; 4503c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.launchKeyboardedDialogActivity(FeedbackActivity.class); 4513c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4523c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 4533c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private ResearchLog mFeedbackLog; 4543c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private List<LogUnit> mFeedbackQueue; 4553c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private ResearchLog mSavedMainResearchLog; 4563c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private ResearchLog mSavedIntentionalResearchLog; 4573c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private List<LogUnit> mSavedIntentionalResearchLogQueue; 4583c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 4593c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private void saveLogsForFeedback() { 4603c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackLog = mIntentionalResearchLog; 4613c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge if (mIntentionalResearchLogQueue != null) { 4623c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackQueue = new ArrayList<LogUnit>(mIntentionalResearchLogQueue); 4633c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } else { 4643c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackQueue = null; 4653c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4663c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mSavedMainResearchLog = mMainResearchLog; 4673c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mSavedIntentionalResearchLog = mIntentionalResearchLog; 4683c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mSavedIntentionalResearchLogQueue = mIntentionalResearchLogQueue; 4693c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 4703c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mMainResearchLog = null; 4713c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLog = null; 4723c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLogQueue = new ArrayList<LogUnit>(); 4733c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4743c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 4753c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private static final int LOG_DRAIN_TIMEOUT_IN_MS = 1000 * 5; 4763c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void sendFeedback(final String feedbackContents, final boolean includeHistory) { 4773c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge if (includeHistory && mFeedbackLog != null) { 4783c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge try { 4793c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge LogUnit headerLogUnit = new LogUnit(); 4803c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge headerLogUnit.addLogAtom(EVENTKEYS_INTENTIONAL_LOG, EVENTKEYS_NULLVALUES, false); 4813c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackLog.publishAllEvents(headerLogUnit); 4823c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge for (LogUnit logUnit : mFeedbackQueue) { 4833c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackLog.publishAllEvents(logUnit); 4843c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4853c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge userFeedback(mFeedbackLog, feedbackContents); 4863c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackLog.stop(); 4873c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge try { 4883c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mFeedbackLog.waitUntilStopped(LOG_DRAIN_TIMEOUT_IN_MS); 4893c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } catch (InterruptedException e) { 4903c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge e.printStackTrace(); 4913c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4923c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLog = new ResearchLog(createLogFile(mFilesDir)); 4933c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLog.start(); 4943c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } catch (IOException e) { 4953c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge e.printStackTrace(); 4963c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } finally { 4973c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLogQueue.clear(); 4983c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 4993c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mResearchLogUploader.uploadNow(null); 5003c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } else { 5013c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge // create a separate ResearchLog just for feedback 5023c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge final ResearchLog feedbackLog = new ResearchLog(createLogFile(mFilesDir)); 5033c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge try { 5043c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge feedbackLog.start(); 5053c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge userFeedback(feedbackLog, feedbackContents); 5063c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge feedbackLog.stop(); 5073c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge feedbackLog.waitUntilStopped(LOG_DRAIN_TIMEOUT_IN_MS); 5083c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mResearchLogUploader.uploadNow(null); 5093c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } catch (IOException e) { 5103c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge e.printStackTrace(); 5113c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } catch (InterruptedException e) { 5123c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge e.printStackTrace(); 5133c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5143c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5153c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5163c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 5173c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void onLeavingSendFeedbackDialog() { 5183c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mInFeedbackDialog = false; 5193c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mMainResearchLog = mSavedMainResearchLog; 5203c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLog = mSavedIntentionalResearchLog; 5213c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mIntentionalResearchLogQueue = mSavedIntentionalResearchLogQueue; 5223c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5233c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 5246080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge public void initSuggest(Suggest suggest) { 5256080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge mSuggest = suggest; 5266080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 5276080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 5281cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private void setIsPasswordView(boolean isPasswordView) { 5291cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge mIsPasswordView = isPasswordView; 5301cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge } 5311cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge 5321cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private boolean isAllowedToLog() { 5330df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return !mIsPasswordView && !mIsLoggingSuspended && sIsLogging; 534223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 535223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 536223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public void requestIndicatorRedraw() { 5374fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (!IS_SHOWING_INDICATOR) { 5384fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge return; 5394fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 5404fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (mKeyboardSwitcher == null) { 5414fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge return; 5424fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 5434fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final KeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView(); 5444fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (keyboardView == null) { 5454fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge return; 5464fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 5474fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge keyboardView.invalidateAllKeys(); 5484fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 5494fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge 5504fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge 5514fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge public void paintIndicator(KeyboardView view, Paint paint, Canvas canvas, int width, 5524fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge int height) { 5534fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // TODO: Reimplement using a keyboard background image specific to the ResearchLogger 5544fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // and remove this method. 555c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka // The check for MainKeyboardView ensures that a red border is only placed around 5564fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // the main keyboard, not every keyboard. 557c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka if (IS_SHOWING_INDICATOR && isAllowedToLog() && view instanceof MainKeyboardView) { 5584fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final int savedColor = paint.getColor(); 5594fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setColor(Color.RED); 5604fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final Style savedStyle = paint.getStyle(); 5614fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStyle(Style.STROKE); 5624fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final float savedStrokeWidth = paint.getStrokeWidth(); 5634fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (IS_SHOWING_INDICATOR_CLEARLY) { 5644fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(5); 5654fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge canvas.drawRect(0, 0, width, height, paint); 5664fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } else { 5674fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // Put a tiny red dot on the screen so a knowledgeable user can check whether 5684fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // it is enabled. The dot is actually a zero-width, zero-height rectangle, 5694fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // placed at the lower-right corner of the canvas, painted with a non-zero border 5704fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // width. 5714fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(3); 5724fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge canvas.drawRect(width, height, width, height, paint); 5730df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 5744fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setColor(savedColor); 5754fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStyle(savedStyle); 5764fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(savedStrokeWidth); 577223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 5781cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge } 5791cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge 58007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String CURRENT_TIME_KEY = "_ct"; 58107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String UPTIME_KEY = "_ut"; 58207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String EVENT_TYPE_KEY = "_ty"; 58307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final Object[] EVENTKEYS_NULLVALUES = {}; 584d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 5856080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private LogUnit mCurrentLogUnit = new LogUnit(); 5866080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 58707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge /** 5886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * Buffer a research log event, flagging it as privacy-sensitive. 58907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * 5906080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * This event contains potentially private information. If the word that this event is a part 5916080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * of is determined to be privacy-sensitive, then this event should not be included in the 5926080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * output log. The system waits to output until the containing word is known. 59307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * 59407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * @param keys an array containing a descriptive name for the event, followed by the keys 59507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * @param values an array of values, either a String or Number. length should be one 59607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * less than the keys array 59707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge */ 5986080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private synchronized void enqueuePotentiallyPrivateEvent(final String[] keys, 5996080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final Object[] values) { 60007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge assert values.length + 1 == keys.length; 601223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isAllowedToLog()) { 602223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mCurrentLogUnit.addLogAtom(keys, values, true); 603223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 6046080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 6056080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 6066080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge /** 6076080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * Buffer a research log event, flaggint it as not privacy-sensitive. 6086080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * 6096080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * This event contains no potentially private information. Even if the word that this event 6106080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * is privacy-sensitive, this event can still safely be sent to the output log. The system 6116080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * waits until the containing word is known so that this event can be written in the proper 6126080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * temporal order with other events that may be privacy sensitive. 6136080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * 6146080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * @param keys an array containing a descriptive name for the event, followed by the keys 6156080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * @param values an array of values, either a String or Number. length should be one 6166080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * less than the keys array 6176080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge */ 6186080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private synchronized void enqueueEvent(final String[] keys, final Object[] values) { 6196080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge assert values.length + 1 == keys.length; 620223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isAllowedToLog()) { 621223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mCurrentLogUnit.addLogAtom(keys, values, false); 622223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 6236080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 6246080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 625e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // Used to track how often words are logged. Too-frequent logging can leak 626e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // semantics, disclosing private data. 627e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge /* package for test */ static class LoggingFrequencyState { 628e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge private static final int DEFAULT_WORD_LOG_FREQUENCY = 10; 629e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge private int mWordsRemainingToSkip; 630e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge private final int mFrequency; 631e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 632e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge /** 633e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge * Tracks how often words may be uploaded. 634e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge * 635e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge * @param frequency 1=Every word, 2=Every other word, etc. 636e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge */ 637e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge public LoggingFrequencyState(int frequency) { 638e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mFrequency = frequency; 639e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mWordsRemainingToSkip = mFrequency; 640e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 641e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 642e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge public void onWordLogged() { 643e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mWordsRemainingToSkip = mFrequency; 644e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 645e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 646e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge public void onWordNotLogged() { 647e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge if (mWordsRemainingToSkip > 1) { 648e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mWordsRemainingToSkip--; 649e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 650e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 651e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 652e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge public boolean isSafeToLog() { 653e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge return mWordsRemainingToSkip <= 1; 654e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 655e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 656e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 657e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge /* package for test */ LoggingFrequencyState mLoggingFrequencyState = 658e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge new LoggingFrequencyState(LoggingFrequencyState.DEFAULT_WORD_LOG_FREQUENCY); 659e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 66033d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge /* package for test */ boolean isPrivacyThreat(String word) { 661e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // Current checks: 662e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // - Word not in dictionary 663e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // - Word contains numbers 664e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge // - Privacy-safe word not logged recently 66533d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (TextUtils.isEmpty(word)) { 66633d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge return false; 66733d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 668e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge if (!mLoggingFrequencyState.isSafeToLog()) { 669e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge return true; 670e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 67133d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge final int length = word.length(); 67233d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge boolean hasLetter = false; 67333d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { 67433d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge final int codePoint = Character.codePointAt(word, i); 67533d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (Character.isDigit(codePoint)) { 67633d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge return true; 67733d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 67833d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (Character.isLetter(codePoint)) { 67933d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge hasLetter = true; 68033d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge break; // Word may contain digits, but will only be allowed if in the dictionary. 68133d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 68233d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 68333d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (hasLetter) { 68433d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (mDictionary == null && mSuggest != null && mSuggest.hasMainDictionary()) { 68533d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge mDictionary = mSuggest.getMainDictionary(); 68633d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 68733d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge if (mDictionary == null) { 68833d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge // Can't access dictionary. Assume privacy threat. 68933d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge return true; 69033d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 69133d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge return !(mDictionary.isValidWord(word)); 69233d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 69333d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge // No letters, no numbers. Punctuation, space, or something else. 69433d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge return false; 6956080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 6966080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 697e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge private void onWordComplete(String word) { 698223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isPrivacyThreat(word)) { 699223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge publishLogUnit(mCurrentLogUnit, true); 700e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mLoggingFrequencyState.onWordNotLogged(); 701e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } else { 702223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge publishLogUnit(mCurrentLogUnit, false); 703e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge mLoggingFrequencyState.onWordLogged(); 704e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 705223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mCurrentLogUnit = new LogUnit(); 706e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 707e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 708223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private void publishLogUnit(LogUnit logUnit, boolean isPrivacySensitive) { 7090df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!isAllowedToLog()) { 7100df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return; 7110df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 7120df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (mMainResearchLog == null) { 7130df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return; 7140df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 715223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isPrivacySensitive) { 716223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.publishPublicEvents(logUnit); 717223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } else { 718223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mMainResearchLog.publishAllEvents(logUnit); 7196080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 720223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mIntentionalResearchLogQueue.add(logUnit); 7216080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7226080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 723223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ void publishCurrentLogUnit(ResearchLog researchLog, boolean isPrivacySensitive) { 724223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge publishLogUnit(mCurrentLogUnit, isPrivacySensitive); 7256080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7266080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 727223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge static class LogUnit { 7286080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private final List<String[]> mKeysList = new ArrayList<String[]>(); 7296080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private final List<Object[]> mValuesList = new ArrayList<Object[]>(); 7306080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private final List<Boolean> mIsPotentiallyPrivate = new ArrayList<Boolean>(); 7316080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 7326080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private void addLogAtom(final String[] keys, final Object[] values, 7336080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final Boolean isPotentiallyPrivate) { 7346080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge mKeysList.add(keys); 7356080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge mValuesList.add(values); 7366080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge mIsPotentiallyPrivate.add(isPotentiallyPrivate); 7376080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7386080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 739223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public void publishPublicEventsTo(ResearchLog researchLog) { 740223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge final int size = mKeysList.size(); 741223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge for (int i = 0; i < size; i++) { 742223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (!mIsPotentiallyPrivate.get(i)) { 743223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge researchLog.outputEvent(mKeysList.get(i), mValuesList.get(i)); 744223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 745223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 7466080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7476080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 748223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public void publishAllEventsTo(ResearchLog researchLog) { 749223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge final int size = mKeysList.size(); 750223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge for (int i = 0; i < size; i++) { 751223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge researchLog.outputEvent(mKeysList.get(i), mValuesList.get(i)); 7526080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 75307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 75407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 75507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 756a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge private static int scrubDigitFromCodePoint(int codePoint) { 757a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return Character.isDigit(codePoint) ? DIGIT_REPLACEMENT_CODEPOINT : codePoint; 758a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 759a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge 760a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge /* package for test */ static String scrubDigitsFromString(String s) { 761a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge StringBuilder sb = null; 762a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge final int length = s.length(); 763a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge for (int i = 0; i < length; i = s.offsetByCodePoints(i, 1)) { 76433d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge final int codePoint = Character.codePointAt(s, i); 765a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (Character.isDigit(codePoint)) { 766a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb == null) { 767a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb = new StringBuilder(length); 768a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.append(s.substring(0, i)); 769a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 770a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.appendCodePoint(DIGIT_REPLACEMENT_CODEPOINT); 771a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } else { 772a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb != null) { 773a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.appendCodePoint(codePoint); 774a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 775a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 776a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 777a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb == null) { 778a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return s; 779a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } else { 780a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return sb.toString(); 781a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 782a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 783a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge 7840df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private static String getUUID(final SharedPreferences prefs) { 7850df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge String uuidString = prefs.getString(PREF_RESEARCH_LOGGER_UUID_STRING, null); 7860df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (null == uuidString) { 7870df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge UUID uuid = UUID.randomUUID(); 7880df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge uuidString = uuid.toString(); 7890df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Editor editor = prefs.edit(); 7900df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge editor.putString(PREF_RESEARCH_LOGGER_UUID_STRING, uuidString); 7910df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge editor.apply(); 7920df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 7930df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return uuidString; 7940df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 7950df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 7966080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private String scrubWord(String word) { 7976080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (mDictionary == null) { 7986080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return WORD_REPLACEMENT_STRING; 7996080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 8006080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (mDictionary.isValidWord(word)) { 8016080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return word; 8026080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 8036080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return WORD_REPLACEMENT_STRING; 8046080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 8056080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 8060df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge // Special methods related to startup, shutdown, logging itself 8070df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 808223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private static final String[] EVENTKEYS_INTENTIONAL_LOG = { 809223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge "IntentionalLog" 810223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge }; 8110df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8120df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL = { 8130df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge "LatinIMEOnStartInputViewInternal", "uuid", "packageName", "inputType", "imeOptions", 8140df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge "fieldId", "display", "model", "prefs", "versionCode", "versionName", "outputFormatVersion" 8150df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 8160df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo, 8170df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final SharedPreferences prefs) { 8180df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final ResearchLogger researchLogger = getInstance(); 8193c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge if (researchLogger.mInFeedbackDialog) { 8203c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge researchLogger.saveLogsForFeedback(); 8213c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 8220df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.start(); 8230df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (editorInfo != null) { 8244331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Context context = researchLogger.mInputMethodService; 8250df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge try { 8260df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final PackageInfo packageInfo; 8270df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 8280df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 0); 8290df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final Integer versionCode = packageInfo.versionCode; 8300df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final String versionName = packageInfo.versionName; 8310df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final Object[] values = { 8320df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.mUUIDString, editorInfo.packageName, 8330df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Integer.toHexString(editorInfo.inputType), 8340df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, 8350df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName, 8360df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge OUTPUT_FORMAT_VERSION 8370df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 8380df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values); 8390df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } catch (NameNotFoundException e) { 8400df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.printStackTrace(); 8410df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8420df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8430df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8440df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8450df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge public void latinIME_onFinishInputInternal() { 8460df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge stop(); 8470df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8480df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8490df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = { 8500df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge "LatinIMECommitText", "typedWord" 8510df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 8520df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8530df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge public static void latinIME_commitText(final CharSequence typedWord) { 8540df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final String scrubbedWord = scrubDigitsFromString(typedWord.toString()); 8550df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final Object[] values = { 8560df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge scrubbedWord 8570df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 8580df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final ResearchLogger researchLogger = getInstance(); 8590df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values); 8600df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.onWordComplete(scrubbedWord); 8610df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8620df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8633c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private static final String[] EVENTKEYS_USER_FEEDBACK = { 8643c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge "UserFeedback", "FeedbackContents" 8653c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge }; 8663c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 8673c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private void userFeedback(ResearchLog researchLog, String feedbackContents) { 8683c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge // this method is special; it directs the feedbackContents to a particular researchLog 8693c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge final LogUnit logUnit = new LogUnit(); 8703c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge final Object[] values = { 8713c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge feedbackContents 8723c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge }; 8733c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge logUnit.addLogAtom(EVENTKEYS_USER_FEEDBACK, values, false); 8743c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge researchLog.publishAllEvents(logUnit); 8753c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 8763c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 8770df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge // Regular logging methods 8780df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 879c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_PROCESSMOTIONEVENT = { 880c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewProcessMotionEvent", "action", "eventTime", "id", "x", "y", "size", 88107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "pressure" 88207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 883c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_processMotionEvent(final MotionEvent me, final int action, 88407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final long eventTime, final int index, final int id, final int x, final int y) { 88507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (me != null) { 88607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final String actionString; 88707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge switch (action) { 88807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_CANCEL: actionString = "CANCEL"; break; 88907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_UP: actionString = "UP"; break; 89007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_DOWN: actionString = "DOWN"; break; 89107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_POINTER_UP: actionString = "POINTER_UP"; break; 89207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_POINTER_DOWN: actionString = "POINTER_DOWN"; break; 89307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_MOVE: actionString = "MOVE"; break; 89407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break; 89507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge default: actionString = "ACTION_" + action; break; 896d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 89707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final float size = me.getSize(index); 89807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final float pressure = me.getPressure(index); 89907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 90007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge actionString, eventTime, id, x, y, size, pressure 90107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9026080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 903c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka EVENTKEYS_MAINKEYBOARDVIEW_PROCESSMOTIONEVENT, values); 90407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 905d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 906d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 90707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONCODEINPUT = { 908f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnCodeInput", "code", "x", "y" 90907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 91007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static void latinIME_onCodeInput(final int code, final int x, final int y) { 91107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 912a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y 91307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9146080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values); 915d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 916d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 91707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_CORRECTION = { 918f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LogCorrection", "subgroup", "before", "after", "position" 91907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 92007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static void logCorrection(final String subgroup, final String before, final String after, 92107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final int position) { 92207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 923a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge subgroup, scrubDigitsFromString(before), scrubDigitsFromString(after), position 92407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9256080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_CORRECTION, values); 926b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge } 927b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge 92807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = { 929f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMECommitCurrentAutoCorrection", "typedWord", "autoCorrection" 93007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 931d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_commitCurrentAutoCorrection(final String typedWord, 93260adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge final String autoCorrection) { 93307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 934a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection) 93507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9366080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 9376080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent( 9386080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values); 93960adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge } 94060adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge 94107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = { 942f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEDeleteSurroundingText", "length" 94307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 944d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_deleteSurroundingText(final int length) { 94507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 94607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge length 94707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9486080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values); 949d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 950d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 95107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = { 952f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEDoubleSpaceAutoPeriod" 95307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 954d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_doubleSpaceAutoPeriod() { 9556080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES); 956d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 957d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 95807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = { 959f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnDisplayCompletions", "applicationSpecifiedCompletions" 96007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9619bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void latinIME_onDisplayCompletions( 9629bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final CompletionInfo[] applicationSpecifiedCompletions) { 96307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 96407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge applicationSpecifiedCompletions 96507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9666080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS, 9676080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values); 9689bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 9699bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 9706b966160ac8570271547bf63217efa5e228d4accKurt Partridge public static boolean getAndClearLatinIMEExpectingUpdateSelection() { 97107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge boolean returnValue = sLatinIMEExpectingUpdateSelection; 97207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sLatinIMEExpectingUpdateSelection = false; 973d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge return returnValue; 974d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 975d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge 97607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONWINDOWHIDDEN = { 977f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnWindowHidden", "isTextTruncated", "text" 97807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 979d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge public static void latinIME_onWindowHidden(final int savedSelectionStart, 980d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge final int savedSelectionEnd, final InputConnection ic) { 98107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (ic != null) { 98207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.beginBatchEdit(); 98307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.performContextMenuAction(android.R.id.selectAll); 98407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge CharSequence charSequence = ic.getSelectedText(0); 98507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.setSelection(savedSelectionStart, savedSelectionEnd); 98607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.endBatchEdit(); 98707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sLatinIMEExpectingUpdateSelection = true; 9886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final Object[] values = new Object[2]; 9896080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (OUTPUT_ENTIRE_BUFFER) { 9906080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (TextUtils.isEmpty(charSequence)) { 99107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge values[0] = false; 9926080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = ""; 9936080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 9946080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) { 9956080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE; 9966080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // do not cut in the middle of a supplementary character 9976080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final char c = charSequence.charAt(length - 1); 9986080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (Character.isHighSurrogate(c)) { 9996080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge length--; 10006080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 10016080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final CharSequence truncatedCharSequence = charSequence.subSequence(0, 10026080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge length); 10036080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = true; 10046080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = truncatedCharSequence.toString(); 10056080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 10066080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = false; 10076080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = charSequence.toString(); 10086080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 1009d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 10106080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 10116080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = true; 10126080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = ""; 1013d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 10146080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 10156080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values); 1016223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // Play it safe. Remove privacy-sensitive events. 1017223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge researchLogger.publishLogUnit(researchLogger.mCurrentLogUnit, true); 1018223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge researchLogger.mCurrentLogUnit = new LogUnit(); 10194331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge getInstance().stop(); 1020d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 1021d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 1022d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge 102307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONUPDATESELECTION = { 1024f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnUpdateSelection", "lastSelectionStart", "lastSelectionEnd", "oldSelStart", 102507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "oldSelEnd", "newSelStart", "newSelEnd", "composingSpanStart", "composingSpanEnd", 102686fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "expectingUpdateSelection", "expectingUpdateSelectionFromLogger", "context" 102707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10289bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void latinIME_onUpdateSelection(final int lastSelectionStart, 10299bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int lastSelectionEnd, final int oldSelStart, final int oldSelEnd, 10309bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int newSelStart, final int newSelEnd, final int composingSpanStart, 1031d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge final int composingSpanEnd, final boolean expectingUpdateSelection, 103202308bec632a5df23325c916bffec5def16b22b4Jean Chalard final boolean expectingUpdateSelectionFromLogger, 103302308bec632a5df23325c916bffec5def16b22b4Jean Chalard final RichInputConnection connection) { 103465fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge String word = ""; 103565fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge if (connection != null) { 103665fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge Range range = connection.getWordRangeAtCursor(WHITESPACE_SEPARATORS, 1); 103765fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge if (range != null) { 103865fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge word = range.mWord; 103965fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge } 104065fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge } 10416080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 10426080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final String scrubbedWord = researchLogger.scrubWord(word); 104307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 104407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart, 104507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection, 10466080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge expectingUpdateSelectionFromLogger, scrubbedWord 104707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10486080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values); 104907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 105007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 105107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = { 1052f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPerformEditorAction", "imeActionNext" 105307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1054d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_performEditorAction(final int imeActionNext) { 105507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 105607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge imeActionNext 105707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10586080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values); 1059d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1060d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 106107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = { 1062f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPickApplicationSpecifiedCompletion", "index", "text", "x", "y" 106307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10649bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge public static void latinIME_pickApplicationSpecifiedCompletion(final int index, 106565fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge final CharSequence cs, int x, int y) { 106607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 106765fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge index, cs, x, y 106807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10696080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 10706080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent( 10716080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values); 10729bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge } 10739bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge 107407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = { 1075f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPickSuggestionManually", "replacedWord", "index", "suggestion", "x", "y" 107607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10779bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge public static void latinIME_pickSuggestionManually(final String replacedWord, 10789bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge final int index, CharSequence suggestion, int x, int y) { 107907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1080a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge scrubDigitsFromString(replacedWord), index, suggestion == null ? null : 1081a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge scrubDigitsFromString(suggestion.toString()), x, y 108207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10836080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 10846080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, 10856080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values); 10869bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge } 10879bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge 108807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = { 1089f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPunctuationSuggestion", "index", "suggestion", "x", "y" 109007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10919bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge public static void latinIME_punctuationSuggestion(final int index, 10929bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge final CharSequence suggestion, int x, int y) { 109307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 109465fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge index, suggestion, x, y 109507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10966080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values); 1097d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1098d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 109907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = { 1100f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMERevertDoubleSpaceWhileInBatchEdit" 110107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1102d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_revertDoubleSpaceWhileInBatchEdit() { 11036080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT, 110407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge EVENTKEYS_NULLVALUES); 1105d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1106d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 110707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION = { 1108f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMERevertSwapPunctuation" 110907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1110d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_revertSwapPunctuation() { 11116080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES); 1112d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1113d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 111407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = { 1115f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMESendKeyCodePoint", "code" 111607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1117d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_sendKeyCodePoint(final int code) { 111807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1119a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)) 112007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11216080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values); 1122d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1123d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 112407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = { 1125f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMESwapSwapperAndSpaceWhileInBatchEdit" 112607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1127d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() { 11286080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT, 112907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge EVENTKEYS_NULLVALUES); 11309bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge } 11319bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge 1132c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_ONLONGPRESS = { 1133c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewOnLongPress" 113407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1135c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_onLongPress() { 1136c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES); 11379bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11389bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 1139c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD = { 1140c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewSetKeyboard", "elementId", "locale", "orientation", "width", 114186fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "modeName", "action", "navigateNext", "navigatePrevious", "clobberSettingsKey", 114286fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "passwordInput", "shortcutKeyEnabled", "hasShortcutKey", "languageSwitchKeyEnabled", 114386fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "isMultiLine", "tw", "th", "keys" 114407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1145c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_setKeyboard(final Keyboard keyboard) { 114607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (keyboard != null) { 114786fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge final KeyboardId kid = keyboard.mId; 1148a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge final boolean isPasswordView = kid.passwordInput(); 11490df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge getInstance().setIsPasswordView(isPasswordView); 115007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 115186fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge KeyboardId.elementIdToName(kid.mElementId), 115286fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), 115386fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mOrientation, 115486fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mWidth, 115586fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge KeyboardId.modeName(kid.mMode), 115686fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.imeAction(), 115786fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.navigateNext(), 115886fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.navigatePrevious(), 115986fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mClobberSettingsKey, 11601cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge isPasswordView, 116186fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mShortcutKeyEnabled, 116286fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mHasShortcutKey, 116386fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.mLanguageSwitchKeyEnabled, 116486fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge kid.isMultiLine(), 116586fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge keyboard.mOccupiedWidth, 116686fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge keyboard.mOccupiedHeight, 116786fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge keyboard.mKeys 116886fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge }; 1169c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD, values); 11701cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge getInstance().setIsPasswordView(isPasswordView); 117148a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 117248a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 117348a7681e064ae259b840f0e757da2d716043d893Kurt Partridge 117407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_REVERTCOMMIT = { 1175f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMERevertCommit", "originallyTypedWord" 117607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1177d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_revertCommit(final String originallyTypedWord) { 117807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 117907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge originallyTypedWord 118007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11816080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values); 1182d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1183d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 118407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = { 1185f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnCancelInput" 118607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11879bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnCancelInput() { 11886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT, 118907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge EVENTKEYS_NULLVALUES); 11909bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11919bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 119207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT = { 1193f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnCodeInput", "code", "outputText", "x", "y", 119407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "ignoreModifierKey", "altersCode", "isEnabled" 119507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11969bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnCodeInput(final Key key, final int x, 11979bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int y, final boolean ignoreModifierKey, final boolean altersCode, 11989bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int code) { 119907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key != null) { 120007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge CharSequence outputText = key.mOutputText; 120107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1202a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)), outputText == null ? null 1203a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge : scrubDigitsFromString(outputText.toString()), 1204a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge x, y, ignoreModifierKey, altersCode, key.isEnabled() 120507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12066080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 12076080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values); 12089bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12099bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12109bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 121107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE = { 1212f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnRelease", "code", "withSliding", "ignoreModifierKey", 121307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "isEnabled" 121407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12159bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnRelease(final Key key, final int primaryCode, 12169bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final boolean withSliding, final boolean ignoreModifierKey) { 121707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key != null) { 121807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1219a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding, 1220a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge ignoreModifierKey, key.isEnabled() 122107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12226080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 12236080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values); 12249bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12259bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12269bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 122707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_ONDOWNEVENT = { 1228f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerOnDownEvent", "deltaT", "distanceSquared" 122907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12309bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_onDownEvent(long deltaT, int distanceSquared) { 123107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 123207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge deltaT, distanceSquared 123307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12346080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values); 12359bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12369bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 123707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = { 1238f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerOnMoveEvent", "x", "y", "lastX", "lastY" 123907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12409bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_onMoveEvent(final int x, final int y, final int lastX, 12419bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int lastY) { 124207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 124307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge x, y, lastX, lastY 124407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12456080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values); 12469bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 12479bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 124807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = { 1249f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "SuddenJumpingTouchEventHandlerOnTouchEvent", "motionEvent" 125007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12519bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void suddenJumpingTouchEventHandler_onTouchEvent(final MotionEvent me) { 125207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (me != null) { 125307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 125407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge me.toString() 125507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12566080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 12576080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT, values); 125807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 125907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 126007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 126107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS = { 1262f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "SuggestionsViewSetSuggestions", "suggestedWords" 126307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 126407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static void suggestionsView_setSuggestions(final SuggestedWords suggestedWords) { 126507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (suggestedWords != null) { 126607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 126786fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge suggestedWords 126807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12696080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS, 12706080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values); 1271a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge } 1272a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge } 1273724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge 1274724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge private static final String[] EVENTKEYS_USER_TIMESTAMP = { 1275724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge "UserTimestamp" 1276724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 1277724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge public void userTimestamp() { 12786080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_USER_TIMESTAMP, EVENTKEYS_NULLVALUES); 1279724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 12805a937aae99fbd1c1e6f4976e639ef585e45675e5Kurt Partridge} 1281