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 21b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridgeimport android.app.AlarmManager; 22724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.app.AlertDialog; 234331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.app.Dialog; 24b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridgeimport android.app.PendingIntent; 2573c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.Context; 26724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.content.DialogInterface; 274331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.content.DialogInterface.OnCancelListener; 28b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridgeimport android.content.Intent; 29d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.content.SharedPreferences; 3077814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport android.content.SharedPreferences.Editor; 3173c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.pm.PackageInfo; 3273c5dbd9d262159af3475273b79babe292c75d76Kurt Partridgeimport android.content.pm.PackageManager.NameNotFoundException; 334fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Canvas; 344fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Color; 354fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Paint; 364fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport android.graphics.Paint.Style; 37c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaokaimport android.inputmethodservice.InputMethodService; 3825405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridgeimport android.net.Uri; 3948a7681e064ae259b840f0e757da2d716043d893Kurt Partridgeimport android.os.Build; 404331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.os.IBinder; 410a30688080864e59b12196664e7b3cac10d0a8daKurt Partridgeimport android.os.SystemClock; 42d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.text.TextUtils; 4381dae8d015f63834b2ded44424636b625ece7736Kurt Partridgeimport android.text.format.DateUtils; 44d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.util.Log; 4594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridgeimport android.view.KeyEvent; 46d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.view.MotionEvent; 474331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.Window; 484331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridgeimport android.view.WindowManager; 499bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.CompletionInfo; 5094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridgeimport android.view.inputmethod.CorrectionInfo; 519bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.EditorInfo; 52d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridgeimport android.view.inputmethod.InputConnection; 53724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridgeimport android.widget.Toast; 54d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 559bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.keyboard.Key; 56d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport com.android.inputmethod.keyboard.Keyboard; 5786fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridgeimport com.android.inputmethod.keyboard.KeyboardId; 584fa6e5726041a22db4f15d99521ea06419401946Kurt Partridgeimport com.android.inputmethod.keyboard.KeyboardView; 59c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaokaimport com.android.inputmethod.keyboard.MainKeyboardView; 605f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaokaimport com.android.inputmethod.latin.CollectionUtils; 61ac78633be28e8990fc3b3a8de192c80966e746e3Tadashi G. Takaokaimport com.android.inputmethod.latin.Constants; 626b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.Dictionary; 636b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.LatinIME; 646b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.R; 656b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.RichInputConnection; 6665fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridgeimport com.android.inputmethod.latin.RichInputConnection.Range; 676b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.Suggest; 686b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.latin.SuggestedWords; 699bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.latin.define.ProductionFlag; 70d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 71d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport java.io.File; 7207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.text.SimpleDateFormat; 7307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Date; 7407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Locale; 7577814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport java.util.UUID; 76d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 77d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge/** 78d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Logs the use of the LatinIME keyboard. 79d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 80d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * This class logs operations on the IME keyboard, including what the user has typed. 81d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Data is stored locally in a file in app-specific storage. 82d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * 8393ebf74bae44728e0d5f7e738ea28376187a876eTadashi G. Takaoka * This functionality is off by default. See {@link ProductionFlag#IS_EXPERIMENTAL}. 84d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge */ 85d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgepublic class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener { 86d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge private static final String TAG = ResearchLogger.class.getSimpleName(); 87fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge private static final boolean DEBUG = false; 886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private static final boolean OUTPUT_ENTIRE_BUFFER = false; // true may disclose private info 896b966160ac8570271547bf63217efa5e228d4accKurt Partridge public static final boolean DEFAULT_USABILITY_STUDY_MODE = false; 9007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge /* package */ static boolean sIsLogging = false; 9158caa775a700e99d18cdca922861f1882bf8d1f4Kurt Partridge private static final int OUTPUT_FORMAT_VERSION = 1; 9207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; 934331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private static final String PREF_RESEARCH_HAS_SEEN_SPLASH = "pref_research_has_seen_splash"; 940df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge /* package */ static final String FILENAME_PREFIX = "researchLog"; 9507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String FILENAME_SUFFIX = ".txt"; 9607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final SimpleDateFormat TIMESTAMP_DATEFORMAT = 97223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge new SimpleDateFormat("yyyyMMddHHmmssS", Locale.US); 984fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge private static final boolean IS_SHOWING_INDICATOR = true; 994fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge private static final boolean IS_SHOWING_INDICATOR_CLEARLY = false; 100bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge public static final int FEEDBACK_WORD_BUFFER_SIZE = 5; 10107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 10207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // constants related to specific log points 103aec44d50a7534d8704a7006b4f90f5e8040a931bKurt Partridge private static final String WHITESPACE_SEPARATORS = " \t\n\r"; 104d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1 10507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String PREF_RESEARCH_LOGGER_UUID_STRING = "pref_research_logger_uuid"; 106d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 10707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final ResearchLogger sInstance = new ResearchLogger(); 10807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // to write to a different filename, e.g., for testing, set mFile before calling start() 109223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ File mFilesDir; 110223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ String mUUIDString; 111223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge /* package */ ResearchLog mMainResearchLog; 112bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // mFeedbackLog records all events for the session, private or not (excepting 113223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // passwords). It is written to permanent storage only if the user explicitly commands 114223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge // the system to do so. 115bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // LogUnits are queued in the LogBuffers and published to the ResearchLogs when words are 116bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // complete. 117bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* package */ ResearchLog mFeedbackLog; 118bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* package */ MainLogBuffer mMainLogBuffer; 119bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* package */ LogBuffer mFeedbackLogBuffer; 120223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 1211cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private boolean mIsPasswordView = false; 122223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private boolean mIsLoggingSuspended = false; 1230df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private SharedPreferences mPrefs; 124d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 125a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge // digits entered by the user are replaced with this codepoint. 126a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge /* package for test */ static final int DIGIT_REPLACEMENT_CODEPOINT = 127a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area" 1286080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // U+E001 is in the "private-use area" 1296080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge /* package for test */ static final String WORD_REPLACEMENT_STRING = "\uE001"; 13081dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final String PREF_LAST_CLEANUP_TIME = "pref_last_cleanup_time"; 13181dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final long DURATION_BETWEEN_DIR_CLEANUP_IN_MS = DateUtils.DAY_IN_MILLIS; 13281dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private static final long MAX_LOGFILE_AGE_IN_MS = DateUtils.DAY_IN_MILLIS; 1330df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge protected static final int SUSPEND_DURATION_IN_MINUTES = 1; 13407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // set when LatinIME should ignore an onUpdateSelection() callback that 13507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge // arises from operations in this class 13607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static boolean sLatinIMEExpectingUpdateSelection = false; 137d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 1386080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // used to check whether words are not unique 1396080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private Suggest mSuggest; 1406080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private Dictionary mDictionary; 141c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka private MainKeyboardView mMainKeyboardView; 1424331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private InputMethodService mInputMethodService; 1430a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge private final Statistics mStatistics; 144b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge 145b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge private Intent mUploadIntent; 146b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge private PendingIntent mUploadPendingIntent; 1479c539d5a5c8e9b36be482fd7ebb2a71a22ef6af0Kurt Partridge 148bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private LogUnit mCurrentLogUnit = new LogUnit(); 149bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge 15007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private ResearchLogger() { 1510a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge mStatistics = Statistics.getInstance(); 15207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 153d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 15407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static ResearchLogger getInstance() { 15507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge return sInstance; 15607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 157d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 158c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka public void init(final InputMethodService ims, final SharedPreferences prefs) { 15907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge assert ims != null; 16007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (ims == null) { 16107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IMS is null; logging is off"); 16207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } else { 16307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge mFilesDir = ims.getFilesDir(); 16407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (mFilesDir == null || !mFilesDir.exists()) { 16507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IME storage directory does not exist."); 166d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 167d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 16807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (prefs != null) { 169223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge mUUIDString = getUUID(prefs); 1700df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!prefs.contains(PREF_USABILITY_STUDY_MODE)) { 1710df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Editor e = prefs.edit(); 1720df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.putBoolean(PREF_USABILITY_STUDY_MODE, DEFAULT_USABILITY_STUDY_MODE); 1730df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.apply(); 1740df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 17507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); 176724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge prefs.registerOnSharedPreferenceChangeListener(this); 17781dae8d015f63834b2ded44424636b625ece7736Kurt Partridge 17881dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long lastCleanupTime = prefs.getLong(PREF_LAST_CLEANUP_TIME, 0L); 17981dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long now = System.currentTimeMillis(); 18081dae8d015f63834b2ded44424636b625ece7736Kurt Partridge if (lastCleanupTime + DURATION_BETWEEN_DIR_CLEANUP_IN_MS < now) { 18181dae8d015f63834b2ded44424636b625ece7736Kurt Partridge final long timeHorizon = now - MAX_LOGFILE_AGE_IN_MS; 18281dae8d015f63834b2ded44424636b625ece7736Kurt Partridge cleanupLoggingDir(mFilesDir, timeHorizon); 18381dae8d015f63834b2ded44424636b625ece7736Kurt Partridge Editor e = prefs.edit(); 18481dae8d015f63834b2ded44424636b625ece7736Kurt Partridge e.putLong(PREF_LAST_CLEANUP_TIME, now); 18581dae8d015f63834b2ded44424636b625ece7736Kurt Partridge e.apply(); 18681dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 187d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 1884331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mInputMethodService = ims; 1890df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mPrefs = prefs; 190b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge mUploadIntent = new Intent(mInputMethodService, UploaderService.class); 191b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge mUploadPendingIntent = PendingIntent.getService(mInputMethodService, 0, mUploadIntent, 0); 192b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge 193b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge if (ProductionFlag.IS_EXPERIMENTAL) { 194b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge scheduleUploadingService(mInputMethodService); 195b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge } 196b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge } 197b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge 198b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge /** 199b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * Arrange for the UploaderService to be run on a regular basis. 200b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * 201b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * Any existing scheduled invocation of UploaderService is removed and rescheduled. This may 202b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * cause problems if this method is called often and frequent updates are required, but since 203b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * the user will likely be sleeping at some point, if the interval is less that the expected 204b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * sleep duration and this method is not called during that time, the service should be invoked 205b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge * at some point. 206b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge */ 207b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge public static void scheduleUploadingService(Context context) { 208b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge final Intent intent = new Intent(context, UploaderService.class); 209b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 210b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge final AlarmManager manager = 211b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 212b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge manager.cancel(pendingIntent); 213b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 214b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge UploaderService.RUN_INTERVAL, UploaderService.RUN_INTERVAL, pendingIntent); 215223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 216223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 21781dae8d015f63834b2ded44424636b625ece7736Kurt Partridge private void cleanupLoggingDir(final File dir, final long time) { 21881dae8d015f63834b2ded44424636b625ece7736Kurt Partridge for (File file : dir.listFiles()) { 21981dae8d015f63834b2ded44424636b625ece7736Kurt Partridge if (file.getName().startsWith(ResearchLogger.FILENAME_PREFIX) && 22081dae8d015f63834b2ded44424636b625ece7736Kurt Partridge file.lastModified() < time) { 22181dae8d015f63834b2ded44424636b625ece7736Kurt Partridge file.delete(); 22281dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 22381dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 22481dae8d015f63834b2ded44424636b625ece7736Kurt Partridge } 22581dae8d015f63834b2ded44424636b625ece7736Kurt Partridge 226c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka public void mainKeyboardView_onAttachedToWindow(final MainKeyboardView mainKeyboardView) { 227c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka mMainKeyboardView = mainKeyboardView; 2284331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge maybeShowSplashScreen(); 2294331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2304331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 231c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka public void mainKeyboardView_onDetachedFromWindow() { 232c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka mMainKeyboardView = null; 233c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka } 234c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka 2354331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private boolean hasSeenSplash() { 2364331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return mPrefs.getBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, false); 2374331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2384331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 2394331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private Dialog mSplashDialog = null; 2404331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 2414331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge private void maybeShowSplashScreen() { 2424331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (hasSeenSplash()) { 2434331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2444331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2454331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (mSplashDialog != null && mSplashDialog.isShowing()) { 2464331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2474331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 248c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka final IBinder windowToken = mMainKeyboardView != null 249c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka ? mMainKeyboardView.getWindowToken() : null; 2504331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (windowToken == null) { 2514331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2524331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 25325405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge final AlertDialog.Builder builder = new AlertDialog.Builder(mInputMethodService) 25425405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setTitle(R.string.research_splash_title) 25525405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setMessage(R.string.research_splash_content) 25625405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setPositiveButton(android.R.string.yes, 25725405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge new DialogInterface.OnClickListener() { 25825405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge @Override 25925405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge public void onClick(DialogInterface dialog, int which) { 26025405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge onUserLoggingConsent(); 26125405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge mSplashDialog.dismiss(); 26225405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge } 26325405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge }) 26425405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setNegativeButton(android.R.string.no, 26525405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge new DialogInterface.OnClickListener() { 26625405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge @Override 26725405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge public void onClick(DialogInterface dialog, int which) { 26825405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge final String packageName = mInputMethodService.getPackageName(); 26925405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge final Uri packageUri = Uri.parse("package:" + packageName); 27025405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, 27125405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge packageUri); 27225405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 27325405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge mInputMethodService.startActivity(intent); 27425405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge } 27525405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge }) 27625405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setCancelable(true) 27725405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge .setOnCancelListener( 27825405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge new OnCancelListener() { 27925405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge @Override 28025405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge public void onCancel(DialogInterface dialog) { 28125405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge mInputMethodService.requestHideSelf(0); 28225405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge } 28325405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge }); 28425405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge mSplashDialog = builder.create(); 2854331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Window w = mSplashDialog.getWindow(); 2864331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final WindowManager.LayoutParams lp = w.getAttributes(); 2874331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge lp.token = windowToken; 2884331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2894331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge w.setAttributes(lp); 2904331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge w.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2914331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge mSplashDialog.show(); 2924331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2934331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 29425405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge public void onUserLoggingConsent() { 29525405eafb05d6f2096922b04e5d9ff2ac2bd1a10Kurt Partridge setLoggingAllowed(true); 2964331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge if (mPrefs == null) { 2974331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge return; 2984331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 2994331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Editor e = mPrefs.edit(); 3004331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge e.putBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, true); 3014331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge e.apply(); 302b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge restart(); 3034331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 3044331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 305bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private void setLoggingAllowed(boolean enableLogging) { 306bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mPrefs == null) { 307bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return; 308bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 309bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge Editor e = mPrefs.edit(); 310bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge e.putBoolean(PREF_USABILITY_STUDY_MODE, enableLogging); 311bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge e.apply(); 312bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge sIsLogging = enableLogging; 313bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 314bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge 315223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge private File createLogFile(File filesDir) { 316223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge final StringBuilder sb = new StringBuilder(); 317223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(FILENAME_PREFIX).append('-'); 318223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(mUUIDString).append('-'); 319223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(TIMESTAMP_DATEFORMAT.format(new Date())); 320223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge sb.append(FILENAME_SUFFIX); 321223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge return new File(filesDir, sb.toString()); 32207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 323b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge 3240a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge private void checkForEmptyEditor() { 3250a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge if (mInputMethodService == null) { 3260a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge return; 3270a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3280a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge final InputConnection ic = mInputMethodService.getCurrentInputConnection(); 3290a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge if (ic == null) { 3300a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge return; 3310a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3320a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge final CharSequence textBefore = ic.getTextBeforeCursor(1, 0); 3330a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge if (!TextUtils.isEmpty(textBefore)) { 3340a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge mStatistics.setIsEmptyUponStarting(false); 3350a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge return; 3360a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3370a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge final CharSequence textAfter = ic.getTextAfterCursor(1, 0); 3380a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge if (!TextUtils.isEmpty(textAfter)) { 3390a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge mStatistics.setIsEmptyUponStarting(false); 3400a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge return; 3410a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3420a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge if (textBefore != null && textAfter != null) { 3430a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge mStatistics.setIsEmptyUponStarting(true); 3440a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3450a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge } 3460a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge 3470df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void start() { 348fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 349fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "start called"); 350fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 3514331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge maybeShowSplashScreen(); 3520df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge updateSuspendedState(); 3530df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 3540a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge mStatistics.reset(); 3550a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge checkForEmptyEditor(); 3560df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (!isAllowedToLog()) { 357724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge // Log.w(TAG, "not in usability mode; not logging"); 358724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge return; 359724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 36007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (mFilesDir == null || !mFilesDir.exists()) { 36107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge Log.w(TAG, "IME storage directory does not exist. Cannot start logging."); 362223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge return; 363223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 364bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer == null) { 365bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainResearchLog = new ResearchLog(createLogFile(mFilesDir)); 366bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer = new MainLogBuffer(mMainResearchLog); 367bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer.setSuggest(mSuggest); 368bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 369bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mFeedbackLogBuffer == null) { 370bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLog = new ResearchLog(createLogFile(mFilesDir)); 371bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // LogBuffer is one more than FEEDBACK_WORD_BUFFER_SIZE, because it must also hold 372bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // the feedback LogUnit itself. 373bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer = new LogBuffer(FEEDBACK_WORD_BUFFER_SIZE + 1); 374b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge } 375d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 376d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 3770df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge /* package */ void stop() { 378fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 379fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "stop called"); 380fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 3810a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge logStatistics(); 382bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge commitCurrentLogUnit(); 3830a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge 384bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer != null) { 385bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge publishLogBuffer(mMainLogBuffer, mMainResearchLog, false /* isIncludingPrivateData */); 38617114054e91d9172f0432171862a72e832838e96Kurt Partridge mMainResearchLog.close(null /* callback */); 387bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer = null; 3880df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 389bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mFeedbackLogBuffer != null) { 39017114054e91d9172f0432171862a72e832838e96Kurt Partridge mFeedbackLog.close(null /* callback */); 391bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer = null; 3920df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 393223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 394223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 395223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public boolean abort() { 396fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 397fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "abort called"); 398fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 399223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge boolean didAbortMainLog = false; 400bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer != null) { 401bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer.clear(); 40248a7681e064ae259b840f0e757da2d716043d893Kurt Partridge try { 403bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge didAbortMainLog = mMainResearchLog.blockingAbort(); 40407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } catch (InterruptedException e) { 405bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // Don't know whether this succeeded or not. We assume not; this is reported 406bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // to the caller. 40748a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 408bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer = null; 409d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 410bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge boolean didAbortFeedbackLog = false; 411bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mFeedbackLogBuffer != null) { 412bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer.clear(); 413724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge try { 414bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge didAbortFeedbackLog = mFeedbackLog.blockingAbort(); 415223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } catch (InterruptedException e) { 416bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // Don't know whether this succeeded or not. We assume not; this is reported 417bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // to the caller. 418223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 419bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer = null; 420223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 421bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return didAbortMainLog && didAbortFeedbackLog; 422223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 423223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 4240df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void restart() { 4250df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge stop(); 4260df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge start(); 4270df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4280df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 4290df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private long mResumeTime = 0L; 4300df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void suspendLoggingUntil(long time) { 4310df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIsLoggingSuspended = true; 4320df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mResumeTime = time; 4330df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 4340df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4350df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 4360df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void resumeLogging() { 4370df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mResumeTime = 0L; 4380df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge updateSuspendedState(); 4390df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 4400df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (isAllowedToLog()) { 4410df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge restart(); 4420df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4430df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4440df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 4450df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private void updateSuspendedState() { 4460df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final long time = System.currentTimeMillis(); 4470df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (time > mResumeTime) { 4480df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge mIsLoggingSuspended = false; 4490df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4500df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 4510df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 45207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge @Override 45307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { 45407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key == null || prefs == null) { 45507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge return; 456d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 45707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); 458724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge if (sIsLogging == false) { 459724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge abort(); 460724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 4610df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge requestIndicatorRedraw(); 462fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge mPrefs = prefs; 463fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge prefsChanged(prefs); 464724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 465724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge 46658eb4d9f27595202927150766d198a0bff15efadKurt Partridge public void onResearchKeySelected(final LatinIME latinIME) { 4673c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge if (mInFeedbackDialog) { 4683c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.makeText(latinIME, R.string.research_please_exit_feedback_form, 4693c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge Toast.LENGTH_LONG).show(); 4703c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge return; 4713c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 47258eb4d9f27595202927150766d198a0bff15efadKurt Partridge presentFeedbackDialog(latinIME); 47358eb4d9f27595202927150766d198a0bff15efadKurt Partridge } 47458eb4d9f27595202927150766d198a0bff15efadKurt Partridge 47558eb4d9f27595202927150766d198a0bff15efadKurt Partridge // TODO: currently unreachable. Remove after being sure no menu is needed. 47658eb4d9f27595202927150766d198a0bff15efadKurt Partridge /* 47758eb4d9f27595202927150766d198a0bff15efadKurt Partridge public void presentResearchDialog(final LatinIME latinIME) { 478724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final CharSequence title = latinIME.getString(R.string.english_ime_research_log); 4790df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final boolean showEnable = mIsLoggingSuspended || !sIsLogging; 480724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final CharSequence[] items = new CharSequence[] { 4813c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.getString(R.string.research_feedback_menu_option), 4823c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge showEnable ? latinIME.getString(R.string.research_enable_session_logging) : 4833c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.getString(R.string.research_do_not_log_this_session) 484724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 485724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 486724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge @Override 487724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge public void onClick(DialogInterface di, int position) { 488724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge di.dismiss(); 489724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge switch (position) { 490724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge case 0: 4913c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge presentFeedbackDialog(latinIME); 492724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge break; 493724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge case 1: 49458eb4d9f27595202927150766d198a0bff15efadKurt Partridge enableOrDisable(showEnable, latinIME); 495223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge break; 496724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 497724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 498223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 499724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 500724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge final AlertDialog.Builder builder = new AlertDialog.Builder(latinIME) 501724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge .setItems(items, listener) 502724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge .setTitle(title); 503724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge latinIME.showOptionDialog(builder.create()); 504d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 50558eb4d9f27595202927150766d198a0bff15efadKurt Partridge */ 506d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 5073c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private boolean mInFeedbackDialog = false; 5083c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void presentFeedbackDialog(LatinIME latinIME) { 5093c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mInFeedbackDialog = true; 5103c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge latinIME.launchKeyboardedDialogActivity(FeedbackActivity.class); 5113c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5123c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 51358eb4d9f27595202927150766d198a0bff15efadKurt Partridge // TODO: currently unreachable. Remove after being sure enable/disable is 51458eb4d9f27595202927150766d198a0bff15efadKurt Partridge // not needed. 51558eb4d9f27595202927150766d198a0bff15efadKurt Partridge /* 51658eb4d9f27595202927150766d198a0bff15efadKurt Partridge public void enableOrDisable(final boolean showEnable, final LatinIME latinIME) { 51758eb4d9f27595202927150766d198a0bff15efadKurt Partridge if (showEnable) { 51858eb4d9f27595202927150766d198a0bff15efadKurt Partridge if (!sIsLogging) { 51958eb4d9f27595202927150766d198a0bff15efadKurt Partridge setLoggingAllowed(true); 52058eb4d9f27595202927150766d198a0bff15efadKurt Partridge } 52158eb4d9f27595202927150766d198a0bff15efadKurt Partridge resumeLogging(); 52258eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast.makeText(latinIME, 52358eb4d9f27595202927150766d198a0bff15efadKurt Partridge R.string.research_notify_session_logging_enabled, 52458eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast.LENGTH_LONG).show(); 52558eb4d9f27595202927150766d198a0bff15efadKurt Partridge } else { 52658eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast toast = Toast.makeText(latinIME, 52758eb4d9f27595202927150766d198a0bff15efadKurt Partridge R.string.research_notify_session_log_deleting, 52858eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast.LENGTH_LONG); 52958eb4d9f27595202927150766d198a0bff15efadKurt Partridge toast.show(); 53058eb4d9f27595202927150766d198a0bff15efadKurt Partridge boolean isLogDeleted = abort(); 53158eb4d9f27595202927150766d198a0bff15efadKurt Partridge final long currentTime = System.currentTimeMillis(); 53258eb4d9f27595202927150766d198a0bff15efadKurt Partridge final long resumeTime = currentTime + 1000 * 60 * 53358eb4d9f27595202927150766d198a0bff15efadKurt Partridge SUSPEND_DURATION_IN_MINUTES; 53458eb4d9f27595202927150766d198a0bff15efadKurt Partridge suspendLoggingUntil(resumeTime); 53558eb4d9f27595202927150766d198a0bff15efadKurt Partridge toast.cancel(); 53658eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast.makeText(latinIME, R.string.research_notify_logging_suspended, 53758eb4d9f27595202927150766d198a0bff15efadKurt Partridge Toast.LENGTH_LONG).show(); 53858eb4d9f27595202927150766d198a0bff15efadKurt Partridge } 53958eb4d9f27595202927150766d198a0bff15efadKurt Partridge } 54058eb4d9f27595202927150766d198a0bff15efadKurt Partridge */ 54158eb4d9f27595202927150766d198a0bff15efadKurt Partridge 542bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private static final String[] EVENTKEYS_FEEDBACK = { 543bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge "UserTimestamp", "contents" 544bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge }; 5453c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void sendFeedback(final String feedbackContents, final boolean includeHistory) { 546bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mFeedbackLogBuffer == null) { 547bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return; 548bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 549b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge if (includeHistory) { 550b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge commitCurrentLogUnit(); 551b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge } else { 552bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer.clear(); 5533c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 554bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final LogUnit feedbackLogUnit = new LogUnit(); 555bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final Object[] values = { 556bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge feedbackContents 557bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge }; 558bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge feedbackLogUnit.addLogStatement(EVENTKEYS_FEEDBACK, values, 559bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge false /* isPotentiallyPrivate */); 560bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer.shiftIn(feedbackLogUnit); 561bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */); 56217114054e91d9172f0432171862a72e832838e96Kurt Partridge mFeedbackLog.close(new Runnable() { 56317114054e91d9172f0432171862a72e832838e96Kurt Partridge @Override 56417114054e91d9172f0432171862a72e832838e96Kurt Partridge public void run() { 56517114054e91d9172f0432171862a72e832838e96Kurt Partridge uploadNow(); 56617114054e91d9172f0432171862a72e832838e96Kurt Partridge } 56717114054e91d9172f0432171862a72e832838e96Kurt Partridge }); 568bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLog = new ResearchLog(createLogFile(mFilesDir)); 5693c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5703c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 571b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge public void uploadNow() { 572fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 573fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "calling uploadNow()"); 574fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 575b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge mInputMethodService.startService(mUploadIntent); 576b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge } 577b5ace11a2e7b88e6b89b6297d5d540f351e48a4aKurt Partridge 5783c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge public void onLeavingSendFeedbackDialog() { 5793c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge mInFeedbackDialog = false; 5803c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge } 5813c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 5826080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge public void initSuggest(Suggest suggest) { 5836080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge mSuggest = suggest; 584bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer != null) { 585bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer.setSuggest(mSuggest); 586bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 5876080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 5886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 5891cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private void setIsPasswordView(boolean isPasswordView) { 5901cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge mIsPasswordView = isPasswordView; 5911cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge } 5921cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge 5931cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge private boolean isAllowedToLog() { 594fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 595fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "iatl: " + 596fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge "mipw=" + mIsPasswordView + 597fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge ", mils=" + mIsLoggingSuspended + 598fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge ", sil=" + sIsLogging + 599fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge ", mInFeedbackDialog=" + mInFeedbackDialog); 600fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 601bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return !mIsPasswordView && !mIsLoggingSuspended && sIsLogging && !mInFeedbackDialog; 602223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 603223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge 604223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge public void requestIndicatorRedraw() { 6054fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (!IS_SHOWING_INDICATOR) { 6064fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge return; 6074fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 608c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka if (mMainKeyboardView == null) { 6094fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge return; 6104fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 611c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka mMainKeyboardView.invalidateAllKeys(); 6124fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } 6134fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge 6144fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge 6154fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge public void paintIndicator(KeyboardView view, Paint paint, Canvas canvas, int width, 6164fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge int height) { 6174fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // TODO: Reimplement using a keyboard background image specific to the ResearchLogger 6184fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // and remove this method. 619c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka // The check for MainKeyboardView ensures that a red border is only placed around 6204fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // the main keyboard, not every keyboard. 621c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka if (IS_SHOWING_INDICATOR && isAllowedToLog() && view instanceof MainKeyboardView) { 6224fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final int savedColor = paint.getColor(); 6234fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setColor(Color.RED); 6244fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final Style savedStyle = paint.getStyle(); 6254fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStyle(Style.STROKE); 6264fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge final float savedStrokeWidth = paint.getStrokeWidth(); 6274fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge if (IS_SHOWING_INDICATOR_CLEARLY) { 6284fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(5); 6294fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge canvas.drawRect(0, 0, width, height, paint); 6304fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge } else { 6314fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // Put a tiny red dot on the screen so a knowledgeable user can check whether 6324fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // it is enabled. The dot is actually a zero-width, zero-height rectangle, 6334fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // placed at the lower-right corner of the canvas, painted with a non-zero border 6344fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge // width. 6354fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(3); 6364fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge canvas.drawRect(width, height, width, height, paint); 6370df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 6384fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setColor(savedColor); 6394fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStyle(savedStyle); 6404fa6e5726041a22db4f15d99521ea06419401946Kurt Partridge paint.setStrokeWidth(savedStrokeWidth); 641223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 6421cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge } 6431cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge 64407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final Object[] EVENTKEYS_NULLVALUES = {}; 645d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 64607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge /** 6476080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * Buffer a research log event, flagging it as privacy-sensitive. 64807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * 6496080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * This event contains potentially private information. If the word that this event is a part 6506080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * of is determined to be privacy-sensitive, then this event should not be included in the 6516080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * output log. The system waits to output until the containing word is known. 65207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * 65307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * @param keys an array containing a descriptive name for the event, followed by the keys 65407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * @param values an array of values, either a String or Number. length should be one 65507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge * less than the keys array 65607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge */ 6576080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private synchronized void enqueuePotentiallyPrivateEvent(final String[] keys, 6586080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final Object[] values) { 65907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge assert values.length + 1 == keys.length; 660223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isAllowedToLog()) { 661bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mCurrentLogUnit.addLogStatement(keys, values, true /* isPotentiallyPrivate */); 662223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 6636080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 6646080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 665bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private void setCurrentLogUnitContainsDigitFlag() { 666bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mCurrentLogUnit.setContainsDigit(); 667bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 668bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge 6696080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge /** 6706080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * Buffer a research log event, flaggint it as not privacy-sensitive. 6716080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * 6726080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * This event contains no potentially private information. Even if the word that this event 6736080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * is privacy-sensitive, this event can still safely be sent to the output log. The system 6746080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * waits until the containing word is known so that this event can be written in the proper 6756080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * temporal order with other events that may be privacy sensitive. 6766080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * 6776080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * @param keys an array containing a descriptive name for the event, followed by the keys 6786080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * @param values an array of values, either a String or Number. length should be one 6796080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge * less than the keys array 6806080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge */ 6816080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private synchronized void enqueueEvent(final String[] keys, final Object[] values) { 6826080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge assert values.length + 1 == keys.length; 683223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge if (isAllowedToLog()) { 684bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mCurrentLogUnit.addLogStatement(keys, values, false /* isPotentiallyPrivate */); 685223d671ffcfe182130742c8a48185b9362acc6f9Kurt Partridge } 6866080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 6876080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 688bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* package for test */ void commitCurrentLogUnit() { 689fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge if (DEBUG) { 690fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge Log.d(TAG, "commitCurrentLogUnit"); 691fe05b881342645f75428cc51849f7326cb76a408Kurt Partridge } 692bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (!mCurrentLogUnit.isEmpty()) { 693bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer != null) { 694bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer.shiftIn(mCurrentLogUnit); 695bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mMainLogBuffer.isSafeToLog() && mMainResearchLog != null) { 696bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge publishLogBuffer(mMainLogBuffer, mMainResearchLog, 697bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge true /* isIncludingPrivateData */); 698bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mMainLogBuffer.resetWordCounter(); 699bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 700bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 701bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (mFeedbackLogBuffer != null) { 702bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mFeedbackLogBuffer.shiftIn(mCurrentLogUnit); 703e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 704bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mCurrentLogUnit = new LogUnit(); 705bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge Log.d(TAG, "commitCurrentLogUnit"); 706e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 707bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 708e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 709bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* package for test */ void publishLogBuffer(final LogBuffer logBuffer, 710bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final ResearchLog researchLog, final boolean isIncludingPrivateData) { 711bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge LogUnit logUnit; 712bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge while ((logUnit = logBuffer.shiftOut()) != null) { 713bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLog.publish(logUnit, isIncludingPrivateData); 714e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 715e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 716e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 717bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private boolean hasOnlyLetters(final String word) { 71833d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge final int length = word.length(); 71933d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { 720bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final int codePoint = word.codePointAt(i); 721bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (!Character.isLetter(codePoint)) { 722bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return false; 72333d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge } 724e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 725bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge return true; 726e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge } 727e961188e9fd4f4365c6c745c8d3d838dd7dfe6a0Kurt Partridge 728bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private void onWordComplete(final String word) { 729bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge Log.d(TAG, "onWordComplete: " + word); 730bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (word != null && word.length() > 0 && hasOnlyLetters(word)) { 731bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mCurrentLogUnit.setWord(word); 732bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge mStatistics.recordWordEntered(); 73307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 734bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge commitCurrentLogUnit(); 73507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 73607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 737a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge private static int scrubDigitFromCodePoint(int codePoint) { 738a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return Character.isDigit(codePoint) ? DIGIT_REPLACEMENT_CODEPOINT : codePoint; 739a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 740a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge 741a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge /* package for test */ static String scrubDigitsFromString(String s) { 742a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge StringBuilder sb = null; 743a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge final int length = s.length(); 744a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge for (int i = 0; i < length; i = s.offsetByCodePoints(i, 1)) { 74533d9f9b6dbafba97d5f46b021727b9d797906baaKurt Partridge final int codePoint = Character.codePointAt(s, i); 746a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (Character.isDigit(codePoint)) { 747a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb == null) { 748a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb = new StringBuilder(length); 749a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.append(s.substring(0, i)); 750a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 751a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.appendCodePoint(DIGIT_REPLACEMENT_CODEPOINT); 752a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } else { 753a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb != null) { 754a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge sb.appendCodePoint(codePoint); 755a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 756a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 757a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 758a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge if (sb == null) { 759a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return s; 760a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } else { 761a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge return sb.toString(); 762a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 763a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge } 764a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge 7650df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private static String getUUID(final SharedPreferences prefs) { 7660df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge String uuidString = prefs.getString(PREF_RESEARCH_LOGGER_UUID_STRING, null); 7670df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (null == uuidString) { 7680df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge UUID uuid = UUID.randomUUID(); 7690df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge uuidString = uuid.toString(); 7700df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Editor editor = prefs.edit(); 7710df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge editor.putString(PREF_RESEARCH_LOGGER_UUID_STRING, uuidString); 7720df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge editor.apply(); 7730df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 7740df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge return uuidString; 7750df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 7760df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 7776080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge private String scrubWord(String word) { 7786080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (mDictionary == null) { 7796080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return WORD_REPLACEMENT_STRING; 7806080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7816080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (mDictionary.isValidWord(word)) { 7826080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return word; 7836080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7846080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge return WORD_REPLACEMENT_STRING; 7856080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 7866080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge 7870df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL = { 7880df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge "LatinIMEOnStartInputViewInternal", "uuid", "packageName", "inputType", "imeOptions", 7890df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge "fieldId", "display", "model", "prefs", "versionCode", "versionName", "outputFormatVersion" 7900df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 7910df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo, 7920df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final SharedPreferences prefs) { 7930df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final ResearchLogger researchLogger = getInstance(); 7940df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.start(); 7950df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge if (editorInfo != null) { 7964331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge final Context context = researchLogger.mInputMethodService; 7970df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge try { 7980df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final PackageInfo packageInfo; 7990df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 8000df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 0); 8010df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final Integer versionCode = packageInfo.versionCode; 8020df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final String versionName = packageInfo.versionName; 8030df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge final Object[] values = { 8040df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.mUUIDString, editorInfo.packageName, 8050df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Integer.toHexString(editorInfo.inputType), 8060df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId, 8070df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName, 8080df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge OUTPUT_FORMAT_VERSION 8090df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge }; 8100df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values); 8110df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } catch (NameNotFoundException e) { 8120df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge e.printStackTrace(); 8130df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8140df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8150df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8160df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8170df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge public void latinIME_onFinishInputInternal() { 8180df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge stop(); 8190df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge } 8200df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 8213c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge private static final String[] EVENTKEYS_USER_FEEDBACK = { 8223c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge "UserFeedback", "FeedbackContents" 8233c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge }; 8243c233bf1a5003c478a27964758afe2ca581d3d8bKurt Partridge 825fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge private static final String[] EVENTKEYS_PREFS_CHANGED = { 826fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge "PrefsChanged", "prefs" 827fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge }; 828fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge public static void prefsChanged(final SharedPreferences prefs) { 829fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge final ResearchLogger researchLogger = getInstance(); 830fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge final Object[] values = { 831fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge prefs 832fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge }; 833fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_PREFS_CHANGED, values); 834fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge } 835fa0bac9057e2dbb0b1aacc6d748a8bcf12ac1462Kurt Partridge 8360df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge // Regular logging methods 8370df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge 838c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_PROCESSMOTIONEVENT = { 839c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewProcessMotionEvent", "action", "eventTime", "id", "x", "y", "size", 84007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "pressure" 84107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 842c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_processMotionEvent(final MotionEvent me, final int action, 84307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final long eventTime, final int index, final int id, final int x, final int y) { 84407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (me != null) { 84507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final String actionString; 84607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge switch (action) { 84707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_CANCEL: actionString = "CANCEL"; break; 84807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_UP: actionString = "UP"; break; 84907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_DOWN: actionString = "DOWN"; break; 85007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_POINTER_UP: actionString = "POINTER_UP"; break; 85107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_POINTER_DOWN: actionString = "POINTER_DOWN"; break; 85207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_MOVE: actionString = "MOVE"; break; 85307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break; 85407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge default: actionString = "ACTION_" + action; break; 855d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 85607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final float size = me.getSize(index); 85707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final float pressure = me.getPressure(index); 85807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 85907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge actionString, eventTime, id, x, y, size, pressure 86007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 8616080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 862c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka EVENTKEYS_MAINKEYBOARDVIEW_PROCESSMOTIONEVENT, values); 86307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 864d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 865d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 86607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONCODEINPUT = { 867f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnCodeInput", "code", "x", "y" 86807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 86907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge public static void latinIME_onCodeInput(final int code, final int x, final int y) { 870bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final long time = SystemClock.uptimeMillis(); 871bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final ResearchLogger researchLogger = getInstance(); 87207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 873a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y 87407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 8750a30688080864e59b12196664e7b3cac10d0a8daKurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values); 876bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (Character.isDigit(code)) { 877bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.setCurrentLogUnitContainsDigitFlag(); 878bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 879bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.mStatistics.recordChar(code, time); 880d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge } 881d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge 88207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = { 883f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnDisplayCompletions", "applicationSpecifiedCompletions" 88407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 8859bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void latinIME_onDisplayCompletions( 8869bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final CompletionInfo[] applicationSpecifiedCompletions) { 88707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 88807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge applicationSpecifiedCompletions 88907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 8906080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS, 8916080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values); 8929bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 8939bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 8946b966160ac8570271547bf63217efa5e228d4accKurt Partridge public static boolean getAndClearLatinIMEExpectingUpdateSelection() { 89507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge boolean returnValue = sLatinIMEExpectingUpdateSelection; 89607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sLatinIMEExpectingUpdateSelection = false; 897d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge return returnValue; 898d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 899d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge 90007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONWINDOWHIDDEN = { 901f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnWindowHidden", "isTextTruncated", "text" 90207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 903d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge public static void latinIME_onWindowHidden(final int savedSelectionStart, 904d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge final int savedSelectionEnd, final InputConnection ic) { 90507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (ic != null) { 90694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge // Capture the TextView contents. This will trigger onUpdateSelection(), so we 90794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge // set sLatinIMEExpectingUpdateSelection so that when onUpdateSelection() is called, 90894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge // it can tell that it was generated by the logging code, and not by the user, and 90994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge // therefore keep user-visible state as is. 91007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.beginBatchEdit(); 91107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.performContextMenuAction(android.R.id.selectAll); 91207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge CharSequence charSequence = ic.getSelectedText(0); 91307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.setSelection(savedSelectionStart, savedSelectionEnd); 91407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge ic.endBatchEdit(); 91507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge sLatinIMEExpectingUpdateSelection = true; 9166080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final Object[] values = new Object[2]; 9176080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (OUTPUT_ENTIRE_BUFFER) { 9186080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (TextUtils.isEmpty(charSequence)) { 91907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge values[0] = false; 9206080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = ""; 9216080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 9226080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) { 9236080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE; 9246080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge // do not cut in the middle of a supplementary character 9256080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final char c = charSequence.charAt(length - 1); 9266080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge if (Character.isHighSurrogate(c)) { 9276080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge length--; 9286080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 9296080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final CharSequence truncatedCharSequence = charSequence.subSequence(0, 9306080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge length); 9316080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = true; 9326080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = truncatedCharSequence.toString(); 9336080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 9346080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = false; 9356080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = charSequence.toString(); 9366080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } 937d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 9386080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge } else { 9396080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[0] = true; 9406080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values[1] = ""; 941d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 9426080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 9436080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values); 944bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.commitCurrentLogUnit(); 9454331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge getInstance().stop(); 946d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 947d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge } 948d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge 94907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_ONUPDATESELECTION = { 950f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEOnUpdateSelection", "lastSelectionStart", "lastSelectionEnd", "oldSelStart", 95107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "oldSelEnd", "newSelStart", "newSelEnd", "composingSpanStart", "composingSpanEnd", 95286fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "expectingUpdateSelection", "expectingUpdateSelectionFromLogger", "context" 95307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9549bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void latinIME_onUpdateSelection(final int lastSelectionStart, 9559bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int lastSelectionEnd, final int oldSelStart, final int oldSelEnd, 9569bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int newSelStart, final int newSelEnd, final int composingSpanStart, 957d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge final int composingSpanEnd, final boolean expectingUpdateSelection, 95802308bec632a5df23325c916bffec5def16b22b4Jean Chalard final boolean expectingUpdateSelectionFromLogger, 95902308bec632a5df23325c916bffec5def16b22b4Jean Chalard final RichInputConnection connection) { 96065fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge String word = ""; 96165fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge if (connection != null) { 96265fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge Range range = connection.getWordRangeAtCursor(WHITESPACE_SEPARATORS, 1); 96365fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge if (range != null) { 96465fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge word = range.mWord; 96565fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge } 96665fc909e13134d34e87d5d75ff4cdd46fb9cebf0Kurt Partridge } 9676080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 9686080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final String scrubbedWord = researchLogger.scrubWord(word); 96907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 97007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart, 97107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection, 9726080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge expectingUpdateSelectionFromLogger, scrubbedWord 97307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9746080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values); 97507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 97607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 97707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = { 978f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPickSuggestionManually", "replacedWord", "index", "suggestion", "x", "y" 97907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9809bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge public static void latinIME_pickSuggestionManually(final String replacedWord, 9816785b9072762e15bb49657ce7b7d228dab76e44aTadashi G. Takaoka final int index, CharSequence suggestion) { 98207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 9836785b9072762e15bb49657ce7b7d228dab76e44aTadashi G. Takaoka scrubDigitsFromString(replacedWord), index, 9846785b9072762e15bb49657ce7b7d228dab76e44aTadashi G. Takaoka (suggestion == null ? null : scrubDigitsFromString(suggestion.toString())), 985ac78633be28e8990fc3b3a8de192c80966e746e3Tadashi G. Takaoka Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE 98607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9876080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge final ResearchLogger researchLogger = getInstance(); 9886080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, 9896080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge values); 9909bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge } 9919bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge 99207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = { 993f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMEPunctuationSuggestion", "index", "suggestion", "x", "y" 99407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 9959bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge public static void latinIME_punctuationSuggestion(final int index, 9966785b9072762e15bb49657ce7b7d228dab76e44aTadashi G. Takaoka final CharSequence suggestion) { 99707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 9986785b9072762e15bb49657ce7b7d228dab76e44aTadashi G. Takaoka index, suggestion, 999ac78633be28e8990fc3b3a8de192c80966e746e3Tadashi G. Takaoka Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE 100007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10016080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values); 1002d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1003d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 100407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = { 1005f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMESendKeyCodePoint", "code" 100607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1007d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_sendKeyCodePoint(final int code) { 100807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1009a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)) 101007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1011bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final ResearchLogger researchLogger = getInstance(); 1012bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values); 1013bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (Character.isDigit(code)) { 1014bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.setCurrentLogUnitContainsDigitFlag(); 1015bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 1016d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1017d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 101894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACE = { 101994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "LatinIMESwapSwapperAndSpace" 102007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 102194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void latinIME_swapSwapperAndSpace() { 102294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge getInstance().enqueueEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACE, EVENTKEYS_NULLVALUES); 10239bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge } 10249bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge 1025c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_ONLONGPRESS = { 1026c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewOnLongPress" 102707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1028c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_onLongPress() { 1029c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES); 10309bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 10319bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 1032c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String[] EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD = { 1033c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka "MainKeyboardViewSetKeyboard", "elementId", "locale", "orientation", "width", 103486fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "modeName", "action", "navigateNext", "navigatePrevious", "clobberSettingsKey", 103586fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "passwordInput", "shortcutKeyEnabled", "hasShortcutKey", "languageSwitchKeyEnabled", 103686fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge "isMultiLine", "tw", "th", "keys" 103707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1038c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka public static void mainKeyboardView_setKeyboard(final Keyboard keyboard) { 103907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (keyboard != null) { 104086fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge final KeyboardId kid = keyboard.mId; 1041a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge final boolean isPasswordView = kid.passwordInput(); 10420df487678eca58bd4732cfd2b6fd03b3c712eb48Kurt Partridge getInstance().setIsPasswordView(isPasswordView); 104307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1044596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge KeyboardId.elementIdToName(kid.mElementId), 1045596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), 1046596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mOrientation, 1047596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mWidth, 1048596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge KeyboardId.modeName(kid.mMode), 1049596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.imeAction(), 1050596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.navigateNext(), 1051596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.navigatePrevious(), 1052596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mClobberSettingsKey, 1053596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge isPasswordView, 1054596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mShortcutKeyEnabled, 1055596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mHasShortcutKey, 1056596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.mLanguageSwitchKeyEnabled, 1057596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge kid.isMultiLine(), 1058596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge keyboard.mOccupiedWidth, 1059596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge keyboard.mOccupiedHeight, 1060596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge keyboard.mKeys 1061596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge }; 10621cef91e4818790ea5419a6ad9ff6e36ac535c763Kurt Partridge getInstance().setIsPasswordView(isPasswordView); 1063596911479cd7cdc3bf999a5260f0be381e30c7cfKurt Partridge getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD, values); 106448a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 106548a7681e064ae259b840f0e757da2d716043d893Kurt Partridge } 106648a7681e064ae259b840f0e757da2d716043d893Kurt Partridge 106707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_LATINIME_REVERTCOMMIT = { 1068f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "LatinIMERevertCommit", "originallyTypedWord" 106907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 1070d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge public static void latinIME_revertCommit(final String originallyTypedWord) { 107107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 107207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge originallyTypedWord 107307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10746080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values); 1075d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge } 1076d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge 107707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = { 1078f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnCancelInput" 107907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10809bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnCancelInput() { 10816080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT, 108207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge EVENTKEYS_NULLVALUES); 10839bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 10849bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 108507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT = { 1086f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnCodeInput", "code", "outputText", "x", "y", 108707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "ignoreModifierKey", "altersCode", "isEnabled" 108807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10899bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnCodeInput(final Key key, final int x, 10909bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int y, final boolean ignoreModifierKey, final boolean altersCode, 10919bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int code) { 109207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key != null) { 109329d5973fd35438a83acf7f44b5d55d5620278ee3Tadashi G. Takaoka String outputText = key.getOutputText(); 109407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1095a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(code)), outputText == null ? null 1096a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge : scrubDigitsFromString(outputText.toString()), 1097a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge x, y, ignoreModifierKey, altersCode, key.isEnabled() 109807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 10996080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 11006080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values); 11019bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11029bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11039bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 110407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE = { 1105f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerCallListenerOnRelease", "code", "withSliding", "ignoreModifierKey", 110607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge "isEnabled" 110707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11089bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_callListenerOnRelease(final Key key, final int primaryCode, 11099bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final boolean withSliding, final boolean ignoreModifierKey) { 111007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (key != null) { 111107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 1112a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge Keyboard.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding, 1113a696781c2b18d8002275aa89e07fa7379661d025Kurt Partridge ignoreModifierKey, key.isEnabled() 111407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11156080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 11166080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values); 11179bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11189bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11199bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 112007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_ONDOWNEVENT = { 1121f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerOnDownEvent", "deltaT", "distanceSquared" 112207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11239bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_onDownEvent(long deltaT, int distanceSquared) { 112407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 112507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge deltaT, distanceSquared 112607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11276080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values); 11289bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11299bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 113007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = { 1131f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "PointerTrackerOnMoveEvent", "x", "y", "lastX", "lastY" 113207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11339bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void pointerTracker_onMoveEvent(final int x, final int y, final int lastX, 11349bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge final int lastY) { 113507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 113607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge x, y, lastX, lastY 113707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 11386080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values); 11399bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge } 11409bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge 114194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITCOMPLETION = { 114294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionCommitCompletion", "completionInfo" 114394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 114494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_commitCompletion(final CompletionInfo completionInfo) { 114594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 114694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge completionInfo 114794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 114894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final ResearchLogger researchLogger = getInstance(); 114994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge researchLogger.enqueuePotentiallyPrivateEvent( 115094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge EVENTKEYS_RICHINPUTCONNECTION_COMMITCOMPLETION, values); 115194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 115294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 1153bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // Disabled for privacy-protection reasons. Because this event comes after 1154bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // richInputConnection_commitText, which is the event used to separate LogUnits, the 1155bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // data in this event can be associated with the next LogUnit, revealing information 1156bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // about the current word even if it was supposed to be suppressed. The occurrance of 1157bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // autocorrection can be determined by examining the difference between the text strings in 1158bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // the last call to richInputConnection_setComposingText before 1159bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // richInputConnection_commitText, so it's not a data loss. 1160bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge // TODO: Figure out how to log this event without loss of privacy. 1161bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* 116294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITCORRECTION = { 1163bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge "RichInputConnectionCommitCorrection", "typedWord", "autoCorrection" 116494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 1165bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge */ 116694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_commitCorrection(CorrectionInfo correctionInfo) { 1167bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge /* 116894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final String typedWord = correctionInfo.getOldText().toString(); 116994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final String autoCorrection = correctionInfo.getNewText().toString(); 117094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 117194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge scrubDigitsFromString(typedWord), scrubDigitsFromString(autoCorrection) 117294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 117394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final ResearchLogger researchLogger = getInstance(); 117494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge researchLogger.enqueuePotentiallyPrivateEvent( 117594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge EVENTKEYS_RICHINPUTCONNECTION_COMMITCORRECTION, values); 1176bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge */ 117794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 117894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 117994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT = { 118094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionCommitText", "typedWord", "newCursorPosition" 118194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 118294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_commitText(final CharSequence typedWord, 118394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final int newCursorPosition) { 118494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final String scrubbedWord = scrubDigitsFromString(typedWord.toString()); 118594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 118694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge scrubbedWord, newCursorPosition 118794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 118894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final ResearchLogger researchLogger = getInstance(); 118994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_COMMITTEXT, 119094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge values); 119194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge researchLogger.onWordComplete(scrubbedWord); 119294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 119394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 119494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT = { 119594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionDeleteSurroundingText", "beforeLength", "afterLength" 119694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 119794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_deleteSurroundingText(final int beforeLength, 119894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final int afterLength) { 119994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 120094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge beforeLength, afterLength 120194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 1202bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 1203bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge EVENTKEYS_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT, values); 120494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 120594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 120694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT = { 120794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionFinishComposingText" 120894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 120994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_finishComposingText() { 121094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT, 121194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge EVENTKEYS_NULLVALUES); 121294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 121394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 121494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_PERFORMEDITORACTION = { 121594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionPerformEditorAction", "imeActionNext" 121694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 121794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_performEditorAction(final int imeActionNext) { 121894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 121994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge imeActionNext 122094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 122194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge getInstance().enqueueEvent(EVENTKEYS_RICHINPUTCONNECTION_PERFORMEDITORACTION, values); 122294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 122394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 122494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SENDKEYEVENT = { 122594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionSendKeyEvent", "eventTime", "action", "code" 122694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 122794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_sendKeyEvent(final KeyEvent keyEvent) { 122894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 122994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge keyEvent.getEventTime(), 123094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge keyEvent.getAction(), 123194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge keyEvent.getKeyCode() 123294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 1233bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_SENDKEYEVENT, 1234bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge values); 123594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 123694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 123794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SETCOMPOSINGTEXT = { 123894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionSetComposingText", "text", "newCursorPosition" 123994e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 124094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_setComposingText(final CharSequence text, 124194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final int newCursorPosition) { 1242bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge if (text == null) { 1243bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge throw new RuntimeException("setComposingText is null"); 1244bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 124594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 124694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge text, newCursorPosition 124794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 1248bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_SETCOMPOSINGTEXT, 1249bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge values); 125094e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 125194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 125294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge private static final String[] EVENTKEYS_RICHINPUTCONNECTION_SETSELECTION = { 125394e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge "RichInputConnectionSetSelection", "from", "to" 125494e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 125594e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge public static void richInputConnection_setSelection(final int from, final int to) { 125694e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge final Object[] values = { 125794e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge from, to 125894e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge }; 1259bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_RICHINPUTCONNECTION_SETSELECTION, 1260bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge values); 126194e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge } 126294e7f4bef970431f509a806d1b92b19fc3b5ce7dKurt Partridge 126307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = { 1264f739119f3ff54d7c37b67b873373b236a45e47e4Kurt Partridge "SuddenJumpingTouchEventHandlerOnTouchEvent", "motionEvent" 126507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12669bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge public static void suddenJumpingTouchEventHandler_onTouchEvent(final MotionEvent me) { 126707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (me != null) { 126807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 126907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge me.toString() 127007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12716080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueuePotentiallyPrivateEvent( 12726080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT, values); 127307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 127407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge } 127507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge 12764702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka private static final String[] EVENTKEYS_SUGGESTIONSTRIPVIEW_SETSUGGESTIONS = { 12774702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka "SuggestionStripViewSetSuggestions", "suggestedWords" 127807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12794702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka public static void suggestionStripView_setSuggestions(final SuggestedWords suggestedWords) { 128007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge if (suggestedWords != null) { 128107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge final Object[] values = { 128286fcadde5d1ca69e4d93dc7cf5e72c763a32ac84Kurt Partridge suggestedWords 128307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge }; 12844702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka getInstance().enqueuePotentiallyPrivateEvent( 12854702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka EVENTKEYS_SUGGESTIONSTRIPVIEW_SETSUGGESTIONS, values); 1286a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge } 1287a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge } 1288724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge 1289724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge private static final String[] EVENTKEYS_USER_TIMESTAMP = { 1290724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge "UserTimestamp" 1291724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge }; 1292724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge public void userTimestamp() { 12936080f6878b10916013a8a5e1d5f58f8041452c56Kurt Partridge getInstance().enqueueEvent(EVENTKEYS_USER_TIMESTAMP, EVENTKEYS_NULLVALUES); 1294724bc479f7d796d6ce5d5e200216bea855b818b2Kurt Partridge } 1295bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge 1296bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private static final String[] EVENTKEYS_STATISTICS = { 1297bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge "Statistics", "charCount", "letterCount", "numberCount", "spaceCount", "deleteOpsCount", 1298bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge "wordCount", "isEmptyUponStarting", "isEmptinessStateKnown", "averageTimeBetweenKeys", 1299bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge "averageTimeBeforeDelete", "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete" 1300bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge }; 1301bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge private static void logStatistics() { 1302bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final ResearchLogger researchLogger = getInstance(); 1303bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final Statistics statistics = researchLogger.mStatistics; 1304bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge final Object[] values = { 1305bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mCharCount, statistics.mLetterCount, statistics.mNumberCount, 1306bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mSpaceCount, statistics.mDeleteKeyCount, 1307bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mWordCount, statistics.mIsEmptyUponStarting, 1308bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(), 1309bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mBeforeDeleteKeyCounter.getAverageTime(), 1310bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(), 1311bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge statistics.mAfterDeleteKeyCounter.getAverageTime() 1312bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge }; 1313bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge researchLogger.enqueueEvent(EVENTKEYS_STATISTICS, values); 1314bf653996eab40e2c66cfd2eaeb48ed5175b78455Kurt Partridge } 13155a937aae99fbd1c1e6f4976e639ef585e45675e5Kurt Partridge} 1316