ResearchLogger.java revision 07cd1e1731a07ae014a78db59b518ff0dbce3e35
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
17d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgepackage com.android.inputmethod.latin;
18d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
19d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.content.SharedPreferences;
2077814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport android.content.SharedPreferences.Editor;
21d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.inputmethodservice.InputMethodService;
2248a7681e064ae259b840f0e757da2d716043d893Kurt Partridgeimport android.os.Build;
23d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.os.Handler;
24d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.os.HandlerThread;
25d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.os.Process;
262482e6c386f2bd6bffa336a95229caf53508b3b2Kurt Partridgeimport android.os.SystemClock;
27d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.text.TextUtils;
2807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport android.util.JsonWriter;
29d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.util.Log;
30d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport android.view.MotionEvent;
319bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.CompletionInfo;
329bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport android.view.inputmethod.EditorInfo;
33d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridgeimport android.view.inputmethod.InputConnection;
34d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
359bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.keyboard.Key;
369bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.keyboard.KeyDetector;
37d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport com.android.inputmethod.keyboard.Keyboard;
389bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.keyboard.internal.KeyboardState;
399bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridgeimport com.android.inputmethod.latin.define.ProductionFlag;
40d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
41b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridgeimport java.io.BufferedWriter;
42d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgeimport java.io.File;
43b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridgeimport java.io.FileWriter;
44b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridgeimport java.io.IOException;
4507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.io.OutputStream;
4607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.io.OutputStreamWriter;
4707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.text.SimpleDateFormat;
4807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Date;
4907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridgeimport java.util.Locale;
5048a7681e064ae259b840f0e757da2d716043d893Kurt Partridgeimport java.util.Map;
5177814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridgeimport java.util.UUID;
52d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
53d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge/**
54d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Logs the use of the LatinIME keyboard.
55d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge *
56d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * This class logs operations on the IME keyboard, including what the user has typed.
57d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge * Data is stored locally in a file in app-specific storage.
58d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge *
59c166697e3f5ec600089987dbbff0be7f3e308565Ken Wakasa * This functionality is off by default. See {@link ProductionFlag.IS_EXPERIMENTAL}.
60d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge */
61d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridgepublic class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
62d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    private static final String TAG = ResearchLogger.class.getSimpleName();
639bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    private static final boolean DEBUG = false;
6407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    /* package */ static boolean sIsLogging = false;
6507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
6607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String FILENAME_PREFIX = "researchLog";
6707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String FILENAME_SUFFIX = ".txt";
6807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final JsonWriter NULL_JSON_WRITER = new JsonWriter(
6907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            new OutputStreamWriter(new NullOutputStream()));
7007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final SimpleDateFormat TIMESTAMP_DATEFORMAT =
7107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            new SimpleDateFormat("yyyyMMDDHHmmss", Locale.US);
7207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
7307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    // constants related to specific log points
74aec44d50a7534d8704a7006b4f90f5e8040a931bKurt Partridge    private static final String WHITESPACE_SEPARATORS = " \t\n\r";
75d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge    private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1
7607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String PREF_RESEARCH_LOGGER_UUID_STRING = "pref_research_logger_uuid";
77d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
7807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final ResearchLogger sInstance = new ResearchLogger();
7907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private HandlerThread mHandlerThread;
8007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    /* package */ Handler mLoggingHandler;
8107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    // to write to a different filename, e.g., for testing, set mFile before calling start()
8207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private File mFilesDir;
8307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    /* package */ File mFile;
8407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private JsonWriter mJsonWriter = NULL_JSON_WRITER; // should never be null
85d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
8607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private int mLoggingState;
8707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final int LOGGING_STATE_OFF = 0;
8807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final int LOGGING_STATE_ON = 1;
8907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final int LOGGING_STATE_STOPPING = 2;
90d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
9107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    // set when LatinIME should ignore an onUpdateSelection() callback that
9207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    // arises from operations in this class
9307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static boolean sLatinIMEExpectingUpdateSelection = false;
94d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
9507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static class NullOutputStream extends OutputStream {
9607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        /** {@inheritDoc} */
9707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        @Override
9807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        public void write(byte[] buffer, int offset, int count) throws IOException {
9907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            // nop
100d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
101d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
10207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        /** {@inheritDoc} */
10307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        @Override
10407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        public void write(byte[] buffer) throws IOException {
10507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            // nop
106d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
107d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
10807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        @Override
10907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        public void write(int oneByte) {
110b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge        }
11107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
112b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge
11307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private ResearchLogger() {
11407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        mLoggingState = LOGGING_STATE_OFF;
11507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
116d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
11707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static ResearchLogger getInstance() {
11807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        return sInstance;
11907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
120d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
12107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public void init(final InputMethodService ims, final SharedPreferences prefs) {
12207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        assert ims != null;
12307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (ims == null) {
12407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Log.w(TAG, "IMS is null; logging is off");
12507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        } else {
12607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            mFilesDir = ims.getFilesDir();
12707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (mFilesDir == null || !mFilesDir.exists()) {
12807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                Log.w(TAG, "IME storage directory does not exist.");
129d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge            }
130d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
13107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (prefs != null) {
13207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
13307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            prefs.registerOnSharedPreferenceChangeListener(sInstance);
134d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
13507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
136b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge
13707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public synchronized void start() {
13807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        Log.d(TAG, "start called");
13907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (mFilesDir == null || !mFilesDir.exists()) {
14007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Log.w(TAG, "IME storage directory does not exist.  Cannot start logging.");
14107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        } else {
14207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (mHandlerThread == null || !mHandlerThread.isAlive()) {
14307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mHandlerThread = new HandlerThread("ResearchLogger logging task",
14407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        Process.THREAD_PRIORITY_BACKGROUND);
14507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mHandlerThread.start();
14607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mLoggingHandler = null;
14707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mLoggingState = LOGGING_STATE_OFF;
148b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge            }
14907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (mLoggingHandler == null) {
15007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mLoggingHandler = new Handler(mHandlerThread.getLooper());
15107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mLoggingState = LOGGING_STATE_OFF;
152b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge            }
15307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (mFile == null) {
15407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                final String timestampString = TIMESTAMP_DATEFORMAT.format(new Date());
15507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                mFile = new File(mFilesDir, FILENAME_PREFIX + timestampString + FILENAME_SUFFIX);
156b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge            }
15707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (mLoggingState == LOGGING_STATE_OFF) {
158b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge                try {
15907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mJsonWriter = new JsonWriter(new BufferedWriter(new FileWriter(mFile)));
16007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mJsonWriter.setLenient(true);
16107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mJsonWriter.beginArray();
16207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mLoggingState = LOGGING_STATE_ON;
163b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge                } catch (IOException e) {
16407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    Log.w(TAG, "cannot start JsonWriter");
16507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mJsonWriter = NULL_JSON_WRITER;
166b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge                    e.printStackTrace();
167b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge                }
168b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge            }
169b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge        }
170d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
171d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
17207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public synchronized void stop() {
17307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        Log.d(TAG, "stop called");
17407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (mLoggingHandler != null && mLoggingState == LOGGING_STATE_ON) {
17507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            mLoggingState = LOGGING_STATE_STOPPING;
17607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            // put this in the Handler queue so pending writes are processed first.
17707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            mLoggingHandler.post(new Runnable() {
17807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                @Override
17907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                public void run() {
18007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    try {
18107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        Log.d(TAG, "closing jsonwriter");
18207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.endArray();
18307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.flush();
18407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.close();
18507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    } catch (IllegalStateException e1) {
18607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        // assume that this is just the json not being terminated properly.
18707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        // ignore
18807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        e1.printStackTrace();
18907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    } catch (IOException e) {
19007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        e.printStackTrace();
19107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    }
19207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mJsonWriter = NULL_JSON_WRITER;
19307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mFile = null;
19407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    mLoggingState = LOGGING_STATE_OFF;
19507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    if (DEBUG) {
19607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        Log.d(TAG, "logfile closed");
19707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    }
19807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    Log.d(TAG, "finished stop(), notifying");
19907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    synchronized (ResearchLogger.this) {
20007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        ResearchLogger.this.notify();
20107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    }
20207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                }
20307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            });
20448a7681e064ae259b840f0e757da2d716043d893Kurt Partridge            try {
20507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                wait();
20607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            } catch (InterruptedException e) {
20748a7681e064ae259b840f0e757da2d716043d893Kurt Partridge                e.printStackTrace();
20848a7681e064ae259b840f0e757da2d716043d893Kurt Partridge            }
209d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
210d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
211d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
21207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    /* package */ synchronized void flush() {
21307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        try {
21407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            mJsonWriter.flush();
21507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        } catch (IOException e) {
21607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            e.printStackTrace();
217d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
218d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
219d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
22007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    @Override
22107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
22207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (key == null || prefs == null) {
22307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            return;
224d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge        }
22507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false);
226d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
227d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
22807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String CURRENT_TIME_KEY = "_ct";
22907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String UPTIME_KEY = "_ut";
23007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String EVENT_TYPE_KEY = "_ty";
23107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final Object[] EVENTKEYS_NULLVALUES = {};
232d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
23307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    /**
23407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     * Write a description of the event out to the ResearchLog.
23507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     *
23607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     * Runs in the background to avoid blocking the UI thread.
23707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     *
23807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     * @param keys an array containing a descriptive name for the event, followed by the keys
23907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     * @param values an array of values, either a String or Number.  length should be one
24007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     * less than the keys array
24107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge     */
24207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private synchronized void writeEvent(final String[] keys, final Object[] values) {
24307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        assert values.length + 1 == keys.length;
24407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (mLoggingState == LOGGING_STATE_ON) {
24507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            mLoggingHandler.post(new Runnable() {
24607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                @Override
24707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                public void run() {
24848a7681e064ae259b840f0e757da2d716043d893Kurt Partridge                    try {
24907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.beginObject();
25007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
25107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.name(UPTIME_KEY).value(SystemClock.uptimeMillis());
25207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.name(EVENT_TYPE_KEY).value(keys[0]);
25307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        final int length = values.length;
25407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        for (int i = 0; i < length; i++) {
25507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            mJsonWriter.name(keys[i + 1]);
25607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            Object value = values[i];
25707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            if (value instanceof String) {
25807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.value((String) value);
25907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value instanceof Number) {
26007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.value((Number) value);
26107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value instanceof Boolean) {
26207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.value((Boolean) value);
26307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value instanceof CompletionInfo[]) {
26407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                CompletionInfo[] ci = (CompletionInfo[]) value;
26507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.beginArray();
26607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                for (int j = 0; j < ci.length; j++) {
26707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.value(ci[j].toString());
26807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                }
26907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.endArray();
27007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value instanceof SharedPreferences) {
27107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                SharedPreferences prefs = (SharedPreferences) value;
27207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.beginObject();
27307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
27407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name(entry.getKey());
27507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    final Object innerValue = entry.getValue();
27607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    if (innerValue == null) {
27707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                        mJsonWriter.nullValue();
27807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    } else {
27907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                        mJsonWriter.value(innerValue.toString());
28007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    }
28107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                }
28207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.endObject();
28307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value instanceof Keyboard) {
28407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                Keyboard keyboard = (Keyboard) value;
28507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.beginArray();
28607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                for (Key key : keyboard.mKeys) {
28707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.beginObject();
28807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("code").value(key.mCode);
28907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("altCode").value(key.mAltCode);
29007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("x").value(key.mX);
29107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("y").value(key.mY);
29207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("w").value(key.mWidth);
29307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.name("h").value(key.mHeight);
29407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                    mJsonWriter.endObject();
29507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                }
29607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.endArray();
29707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else if (value == null) {
29807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.nullValue();
29907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            } else {
30007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                Log.w(TAG, "Unrecognized type to be logged: " +
30107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                        (value == null ? "<null>" : value.getClass().getName()));
30207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                                mJsonWriter.nullValue();
30307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            }
30407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        }
30507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        mJsonWriter.endObject();
30648a7681e064ae259b840f0e757da2d716043d893Kurt Partridge                    } catch (IOException e) {
30748a7681e064ae259b840f0e757da2d716043d893Kurt Partridge                        e.printStackTrace();
30807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        Log.w(TAG, "Error in JsonWriter; disabling logging");
30907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        try {
31007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            mJsonWriter.close();
31107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        } catch (IllegalStateException e1) {
31207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            // assume that this is just the json not being terminated properly.
31307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            // ignore
31407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        } catch (IOException e1) {
31507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            e1.printStackTrace();
31607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        } finally {
31707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                            mJsonWriter = NULL_JSON_WRITER;
31807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        }
31948a7681e064ae259b840f0e757da2d716043d893Kurt Partridge                    }
320d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge                }
32107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            });
32207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        }
32307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
32407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
32507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT = {
32607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINKEYBOARDVIEW_PROCESSMOTIONEVENT", "action", "eventTime", "id", "x", "y", "size",
32707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "pressure"
32807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
32907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static void latinKeyboardView_processMotionEvent(final MotionEvent me, final int action,
33007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final long eventTime, final int index, final int id, final int x, final int y) {
33107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (me != null) {
33207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final String actionString;
33307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            switch (action) {
33407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_CANCEL: actionString = "CANCEL"; break;
33507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_UP: actionString = "UP"; break;
33607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_DOWN: actionString = "DOWN"; break;
33707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_POINTER_UP: actionString = "POINTER_UP"; break;
33807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_POINTER_DOWN: actionString = "POINTER_DOWN"; break;
33907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_MOVE: actionString = "MOVE"; break;
34007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                case MotionEvent.ACTION_OUTSIDE: actionString = "OUTSIDE"; break;
34107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                default: actionString = "ACTION_" + action; break;
342d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge            }
34307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final float size = me.getSize(index);
34407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final float pressure = me.getPressure(index);
34507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
34607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                actionString, eventTime, id, x, y, size, pressure
34707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
34807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_PROCESSMOTIONEVENT, values);
34907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        }
350d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
351d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
35207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_ONCODEINPUT = {
35307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_ONCODEINPUT", "code", "x", "y"
35407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
35507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static void latinIME_onCodeInput(final int code, final int x, final int y) {
35607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
35707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Keyboard.printableCode(code), x, y
35807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
35907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
360d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
361d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge
36207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_CORRECTION = {
36307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "CORRECTION", "subgroup", "before", "after", "position"
36407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
36507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static void logCorrection(final String subgroup, final String before, final String after,
36607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final int position) {
36707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
36807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            subgroup, before, after, position
36907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
37007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_CORRECTION, values);
371b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge    }
372b8e2ae3bc312269897057fccc34cd736c05bcc90Kurt Partridge
37307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_STATECHANGE = {
37407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "STATECHANGE", "subgroup", "details"
37507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
37607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static void logStateChange(final String subgroup, final String details) {
37707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
37807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            subgroup, details
37907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
38007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_STATECHANGE, values);
381d05afa3f4c59641c8fabed034e457cb25f0c57f0Kurt Partridge    }
3829bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
38307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_KEYBOARDSTATE_ONCANCELINPUT = {
38407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "KEYBOARDSTATE_ONCANCELINPUT", "isSinglePointer", "keyboardState"
38507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
3869bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void keyboardState_onCancelInput(final boolean isSinglePointer,
3879bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final KeyboardState keyboardState) {
38807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
38907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            isSinglePointer, keyboardState.toString()
39007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
39107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_KEYBOARDSTATE_ONCANCELINPUT, values);
3929bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
3939bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
39407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_KEYBOARDSTATE_ONCODEINPUT = {
39507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "KEYBOARDSTATE_ONCODEINPUT", "code", "isSinglePointer", "autoCaps", "keyboardState"
39607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
3979bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void keyboardState_onCodeInput(
3989bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int code, final boolean isSinglePointer, final boolean autoCaps,
3999bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final KeyboardState keyboardState) {
40007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
40107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Keyboard.printableCode(code), isSinglePointer, autoCaps, keyboardState.toString()
40207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
40307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_KEYBOARDSTATE_ONCODEINPUT, values);
4049bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
4059bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
40607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_KEYBOARDSTATE_ONLONGPRESSTIMEOUT = {
40707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "KEYBOARDSTATE_ONLONGPRESSTIMEOUT", "code", "keyboardState"
40807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
4099bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void keyboardState_onLongPressTimeout(final int code,
4109bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final KeyboardState keyboardState) {
41107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
41207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Keyboard.printableCode(code), keyboardState.toString()
41307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
41407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_KEYBOARDSTATE_ONLONGPRESSTIMEOUT, values);
4159bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
4169bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
41707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_KEYBOARDSTATE_ONPRESSKEY = {
41807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "KEYBOARDSTATE_ONPRESSKEY", "code", "keyboardState"
41907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
4209bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void keyboardState_onPressKey(final int code,
4219bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final KeyboardState keyboardState) {
42207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
42307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Keyboard.printableCode(code), keyboardState.toString()
42407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
42507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_KEYBOARDSTATE_ONPRESSKEY, values);
4269bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
4279bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
42807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_KEYBOARDSTATE_ONRELEASEKEY = {
42907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "KEYBOARDSTATE_ONRELEASEKEY", "code", "withSliding", "keyboardState"
43007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
4319bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void keyboardState_onReleaseKey(final KeyboardState keyboardState, final int code,
4329bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final boolean withSliding) {
43307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
43407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Keyboard.printableCode(code), withSliding, keyboardState.toString()
43507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
43607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_KEYBOARDSTATE_ONRELEASEKEY, values);
4379bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
4389bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
43907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION = {
44007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_COMMITCURRENTAUTOCORRECTION", "typedWord", "autoCorrection"
44107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
442d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_commitCurrentAutoCorrection(final String typedWord,
44360adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge            final String autoCorrection) {
44407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
44507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            typedWord, autoCorrection
44607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
44707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
44860adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge    }
44960adb8757496fecb8f376a80832c176b35e43d06Kurt Partridge
45007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
45107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_COMMITTEXT", "typedWord"
45207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
453d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_commitText(final CharSequence typedWord) {
45407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
45507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            typedWord.toString()
45607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
45707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
458d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
459d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
46007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
46107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_DELETESURROUNDINGTEXT", "length"
46207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
463d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_deleteSurroundingText(final int length) {
46407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
46507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            length
46607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
46707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT, values);
468d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
469d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
47007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD = {
47107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_DOUBLESPACEAUTOPERIOD"
47207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
473d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_doubleSpaceAutoPeriod() {
47407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_DOUBLESPACEAUTOPERIOD, EVENTKEYS_NULLVALUES);
475d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
476d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
47707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
47807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_ONDISPLAYCOMPLETIONS", "applicationSpecifiedCompletions"
47907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
4809bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void latinIME_onDisplayCompletions(
4819bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final CompletionInfo[] applicationSpecifiedCompletions) {
48207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
48307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            applicationSpecifiedCompletions
48407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
48507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS, values);
4869bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
4879bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
488d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge    /* package */ static boolean getAndClearLatinIMEExpectingUpdateSelection() {
48907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        boolean returnValue = sLatinIMEExpectingUpdateSelection;
49007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        sLatinIMEExpectingUpdateSelection = false;
491d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge        return returnValue;
492d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge    }
493d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge
49407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_ONWINDOWHIDDEN = {
49507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_ONWINDOWHIDDEN", "isTextTruncated", "text"
49607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
497d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge    public static void latinIME_onWindowHidden(final int savedSelectionStart,
498d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge            final int savedSelectionEnd, final InputConnection ic) {
49907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (ic != null) {
50007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            ic.beginBatchEdit();
50107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            ic.performContextMenuAction(android.R.id.selectAll);
50207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            CharSequence charSequence = ic.getSelectedText(0);
50307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            ic.setSelection(savedSelectionStart, savedSelectionEnd);
50407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            ic.endBatchEdit();
50507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            sLatinIMEExpectingUpdateSelection = true;
50607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            Object[] values = new Object[2];
50707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            if (TextUtils.isEmpty(charSequence)) {
50807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                values[0] = false;
50907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                values[1] = "";
51007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            } else {
51107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                if (charSequence.length() > MAX_INPUTVIEW_LENGTH_TO_CAPTURE) {
51207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    int length = MAX_INPUTVIEW_LENGTH_TO_CAPTURE;
51307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    // do not cut in the middle of a supplementary character
51407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    final char c = charSequence.charAt(length - 1);
51507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    if (Character.isHighSurrogate(c)) {
51607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                        length--;
517d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge                    }
51807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    final CharSequence truncatedCharSequence = charSequence.subSequence(0, length);
51907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values[0] = true;
52007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values[1] = truncatedCharSequence.toString();
52107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                } else {
52207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values[0] = false;
52307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values[1] = charSequence.toString();
524d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge                }
525d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge            }
52607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
527d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge        }
528d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge    }
529d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge
53007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL = {
53107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_ONSTARTINPUTVIEWINTERNAL", "uuid", "packageName", "inputType", "imeOptions",
53207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "display", "model", "prefs"
53307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
53407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
53548a7681e064ae259b840f0e757da2d716043d893Kurt Partridge    public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo,
53648a7681e064ae259b840f0e757da2d716043d893Kurt Partridge            final SharedPreferences prefs) {
53707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (editorInfo != null) {
53807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
53907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                getUUID(prefs), editorInfo.packageName, Integer.toHexString(editorInfo.inputType),
54007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                Integer.toHexString(editorInfo.imeOptions), Build.DISPLAY, Build.MODEL, prefs
54107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
54207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_LATINIME_ONSTARTINPUTVIEWINTERNAL, values);
5439bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge        }
5449bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
5459bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
54677814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge    private static String getUUID(final SharedPreferences prefs) {
54777814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge        String uuidString = prefs.getString(PREF_RESEARCH_LOGGER_UUID_STRING, null);
54877814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge        if (null == uuidString) {
54977814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge            UUID uuid = UUID.randomUUID();
55077814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge            uuidString = uuid.toString();
55177814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge            Editor editor = prefs.edit();
55277814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge            editor.putString(PREF_RESEARCH_LOGGER_UUID_STRING, uuidString);
55377814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge            editor.apply();
55477814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge        }
55577814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge        return uuidString;
55677814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge    }
55777814c4bb0670c3a20c5e636890d70ea1a144409Kurt Partridge
55807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_ONUPDATESELECTION = {
55907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_ONUPDATESELECTION", "lastSelectionStart", "lastSelectionEnd", "oldSelStart",
56007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "oldSelEnd", "newSelStart", "newSelEnd", "composingSpanStart", "composingSpanEnd",
56107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "expectingUpdateSelection", "expectingUpdateSelectionFromLogger", "context"
56207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
56307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
5649bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void latinIME_onUpdateSelection(final int lastSelectionStart,
5659bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int lastSelectionEnd, final int oldSelStart, final int oldSelEnd,
5669bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int newSelStart, final int newSelEnd, final int composingSpanStart,
567d67a248de45a698d1009757c9f4e750c77bf35f1Kurt Partridge            final int composingSpanEnd, final boolean expectingUpdateSelection,
568aec44d50a7534d8704a7006b4f90f5e8040a931bKurt Partridge            final boolean expectingUpdateSelectionFromLogger, final InputConnection connection) {
56907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
57007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            lastSelectionStart, lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart,
57107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            newSelEnd, composingSpanStart, composingSpanEnd, expectingUpdateSelection,
57207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            expectingUpdateSelectionFromLogger,
57307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            EditingUtils.getWordRangeAtCursor(connection, WHITESPACE_SEPARATORS, 1).mWord
57407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
57507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_ONUPDATESELECTION, values);
57607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
57707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
57807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_PERFORMEDITORACTION = {
57907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_PERFORMEDITORACTION", "imeActionNext"
58007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
581d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_performEditorAction(final int imeActionNext) {
58207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
58307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            imeActionNext
58407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
58507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_PERFORMEDITORACTION, values);
586d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
587d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
58807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION = {
58907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION", "index", "text", "x", "y"
59007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
5919bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    public static void latinIME_pickApplicationSpecifiedCompletion(final int index,
5929bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge            final CharSequence text, int x, int y) {
59307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
59407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            index, text.toString(), x, y
59507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
59607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
5979bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    }
5989bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge
59907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
60007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_PICKSUGGESTIONMANUALLY", "replacedWord", "index", "suggestion", "x", "y"
60107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
6029bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    public static void latinIME_pickSuggestionManually(final String replacedWord,
6039bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge            final int index, CharSequence suggestion, int x, int y) {
60407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
60507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            replacedWord, index, suggestion.toString(), x, y
60607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
60707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY, values);
6089bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    }
6099bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge
61007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
61107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_PUNCTUATIONSUGGESTION", "index", "suggestion", "x", "y"
61207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
6139bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    public static void latinIME_punctuationSuggestion(final int index,
6149bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge            final CharSequence suggestion, int x, int y) {
61507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
61607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            index, suggestion.toString(), x, y
61707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
61807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION, values);
619d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
620d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
62107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT = {
62207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT"
62307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
624d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_revertDoubleSpaceWhileInBatchEdit() {
62507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTDOUBLESPACEWHILEINBATCHEDIT,
62607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                EVENTKEYS_NULLVALUES);
627d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
628d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
62907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION = {
63007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_REVERTSWAPPUNCTUATION"
63107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
632d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_revertSwapPunctuation() {
63307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTSWAPPUNCTUATION, EVENTKEYS_NULLVALUES);
634d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
635d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
63607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_SENDKEYCODEPOINT = {
63707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_SENDKEYCODEPOINT", "code"
63807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
639d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_sendKeyCodePoint(final int code) {
64007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
64107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            code
64207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
64307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
644d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
645d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
64607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT = {
64707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT"
64807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
649d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_swapSwapperAndSpaceWhileInBatchEdit() {
65007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_SWAPSWAPPERANDSPACEWHILEINBATCHEDIT,
65107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                EVENTKEYS_NULLVALUES);
6529bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge    }
6539bfb6202154e06d7156f2f374dd9359f1be4eb68Kurt Partridge
65407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW = {
65507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_SWITCHTOKEYBOARDVIEW"
65607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
6579bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void latinIME_switchToKeyboardView() {
65807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_SWITCHTOKEYBOARDVIEW, EVENTKEYS_NULLVALUES);
6599bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
6609bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
66107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS = {
66207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINKEYBOARDVIEW_ONLONGPRESS"
66307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
6649bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void latinKeyboardView_onLongPress() {
66507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_ONLONGPRESS, EVENTKEYS_NULLVALUES);
6669bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
6679bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
66807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD = {
66907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINKEYBOARDVIEW_SETKEYBOARD", "id", "tw", "th", "keys"
67007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
67148a7681e064ae259b840f0e757da2d716043d893Kurt Partridge    public static void latinKeyboardView_setKeyboard(final Keyboard keyboard) {
67207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (keyboard != null) {
67307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
67407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                keyboard.mId.toString(), keyboard.mOccupiedWidth, keyboard.mOccupiedHeight,
67507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                keyboard
67607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
67707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_LATINKEYBOARDVIEW_SETKEYBOARD, values);
67848a7681e064ae259b840f0e757da2d716043d893Kurt Partridge        }
67948a7681e064ae259b840f0e757da2d716043d893Kurt Partridge    }
68048a7681e064ae259b840f0e757da2d716043d893Kurt Partridge
68107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_LATINIME_REVERTCOMMIT = {
68207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "LATINIME_REVERTCOMMIT", "originallyTypedWord"
68307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
684d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    public static void latinIME_revertCommit(final String originallyTypedWord) {
68507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
68607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            originallyTypedWord
68707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
68807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_LATINIME_REVERTCOMMIT, values);
689d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge    }
690d442984e96cc6299c905141e3e32e0a4f55394c8Kurt Partridge
69107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT = {
69207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "POINTERTRACKER_CALLLISTENERONCANCELINPUT"
69307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
6949bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_callListenerOnCancelInput() {
69507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCANCELINPUT,
69607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                EVENTKEYS_NULLVALUES);
6979bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
6989bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
69907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT = {
70007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "POINTERTRACKER_CALLLISTENERONCODEINPUT", "code", "outputText", "x", "y",
70107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "ignoreModifierKey", "altersCode", "isEnabled"
70207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7039bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_callListenerOnCodeInput(final Key key, final int x,
7049bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int y, final boolean ignoreModifierKey, final boolean altersCode,
7059bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int code) {
70607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (key != null) {
70707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            CharSequence outputText = key.mOutputText;
70807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
70907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                Keyboard.printableCode(code), outputText == null ? "" : outputText.toString(),
71007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                x, y, ignoreModifierKey, altersCode, key.isEnabled()
71107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
71207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONCODEINPUT, values);
7139bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge        }
7149bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
7159bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
71607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[]
71707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            EVENTKEYS_POINTERTRACKER_CALLLISTENERONPRESSANDCHECKKEYBOARDLAYOUTCHANGE = {
71807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                "POINTERTRACKER_CALLLISTENERONPRESSANDCHECKKEYBOARDLAYOUTCHANGE", "code",
71907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                "ignoreModifierKey", "isEnabled"
72007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7219bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_callListenerOnPressAndCheckKeyboardLayoutChange(
7229bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final Key key, final boolean ignoreModifierKey) {
72307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (key != null) {
72407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
72507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                KeyDetector.printableCode(key), ignoreModifierKey, key.isEnabled()
72607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
72707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(
72807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    EVENTKEYS_POINTERTRACKER_CALLLISTENERONPRESSANDCHECKKEYBOARDLAYOUTCHANGE,
72907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values);
7309bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge        }
7319bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
7329bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
73307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE = {
73407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "POINTERTRACKER_CALLLISTENERONRELEASE", "code", "withSliding", "ignoreModifierKey",
73507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "isEnabled"
73607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7379bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_callListenerOnRelease(final Key key, final int primaryCode,
7389bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final boolean withSliding, final boolean ignoreModifierKey) {
73907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (key != null) {
74007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
74107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                Keyboard.printableCode(primaryCode), withSliding, ignoreModifierKey,
74207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                key.isEnabled()
74307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
74407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_CALLLISTENERONRELEASE, values);
7459bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge        }
7469bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
7479bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
74807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_POINTERTRACKER_ONDOWNEVENT = {
74907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "POINTERTRACKER_ONDOWNEVENT", "deltaT", "distanceSquared"
75007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7519bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_onDownEvent(long deltaT, int distanceSquared) {
75207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
75307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            deltaT, distanceSquared
75407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
75507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONDOWNEVENT, values);
7569bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
7579bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
75807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_POINTERTRACKER_ONMOVEEVENT = {
75907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "POINTERTRACKER_ONMOVEEVENT", "x", "y", "lastX", "lastY"
76007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7619bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void pointerTracker_onMoveEvent(final int x, final int y, final int lastX,
7629bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge            final int lastY) {
76307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        final Object[] values = {
76407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            x, y, lastX, lastY
76507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        };
76607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        getInstance().writeEvent(EVENTKEYS_POINTERTRACKER_ONMOVEEVENT, values);
7679bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    }
7689bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge
76907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT = {
77007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT", "motionEvent"
77107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
7729bc29d78a6ce83f77869aa63748176241e29d43cKurt Partridge    public static void suddenJumpingTouchEventHandler_onTouchEvent(final MotionEvent me) {
77307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (me != null) {
77407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
77507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                me.toString()
77607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
77707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT,
77807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                    values);
77907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        }
78007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    }
78107cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge
78207cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    private static final String[] EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS = {
78307cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        "SUGGESTIONSVIEW_SETSUGGESTIONS", "suggestedWords"
78407cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    };
78507cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge    public static void suggestionsView_setSuggestions(final SuggestedWords suggestedWords) {
78607cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge        if (suggestedWords != null) {
78707cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            final Object[] values = {
78807cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge                suggestedWords.toString()
78907cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            };
79007cd1e1731a07ae014a78db59b518ff0dbce3e35Kurt Partridge            getInstance().writeEvent(EVENTKEYS_SUGGESTIONSVIEW_SETSUGGESTIONS, values);
791a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge        }
792a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge    }
7935a937aae99fbd1c1e6f4976e639ef585e45675e5Kurt Partridge}
794