am e15e6c2c
: Merge "Revert "ResearchLogger to track simple statistics"" into jb-mr1-dev
* commit 'e15e6c2c2769abcd35c5c099b2cc5073c98371f0': Revert "ResearchLogger to track simple statistics"
This commit is contained in:
commit
38b5623fcf
2 changed files with 1 additions and 202 deletions
|
@ -34,7 +34,6 @@ import android.graphics.Paint.Style;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -138,12 +137,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
private Dictionary mDictionary;
|
private Dictionary mDictionary;
|
||||||
private KeyboardSwitcher mKeyboardSwitcher;
|
private KeyboardSwitcher mKeyboardSwitcher;
|
||||||
private InputMethodService mInputMethodService;
|
private InputMethodService mInputMethodService;
|
||||||
private final Statistics mStatistics;
|
|
||||||
|
|
||||||
private ResearchLogUploader mResearchLogUploader;
|
private ResearchLogUploader mResearchLogUploader;
|
||||||
|
|
||||||
private ResearchLogger() {
|
private ResearchLogger() {
|
||||||
mStatistics = Statistics.getInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResearchLogger getInstance() {
|
public static ResearchLogger getInstance() {
|
||||||
|
@ -273,35 +270,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
return new File(filesDir, sb.toString());
|
return new File(filesDir, sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForEmptyEditor() {
|
|
||||||
if (mInputMethodService == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final InputConnection ic = mInputMethodService.getCurrentInputConnection();
|
|
||||||
if (ic == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final CharSequence textBefore = ic.getTextBeforeCursor(1, 0);
|
|
||||||
if (!TextUtils.isEmpty(textBefore)) {
|
|
||||||
mStatistics.setIsEmptyUponStarting(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final CharSequence textAfter = ic.getTextAfterCursor(1, 0);
|
|
||||||
if (!TextUtils.isEmpty(textAfter)) {
|
|
||||||
mStatistics.setIsEmptyUponStarting(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (textBefore != null && textAfter != null) {
|
|
||||||
mStatistics.setIsEmptyUponStarting(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
maybeShowSplashScreen();
|
maybeShowSplashScreen();
|
||||||
updateSuspendedState();
|
updateSuspendedState();
|
||||||
requestIndicatorRedraw();
|
requestIndicatorRedraw();
|
||||||
mStatistics.reset();
|
|
||||||
checkForEmptyEditor();
|
|
||||||
if (!isAllowedToLog()) {
|
if (!isAllowedToLog()) {
|
||||||
// Log.w(TAG, "not in usability mode; not logging");
|
// Log.w(TAG, "not in usability mode; not logging");
|
||||||
return;
|
return;
|
||||||
|
@ -325,10 +297,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void stop() {
|
/* package */ void stop() {
|
||||||
logStatistics();
|
|
||||||
publishLogUnit(mCurrentLogUnit, true);
|
|
||||||
mCurrentLogUnit = new LogUnit();
|
|
||||||
|
|
||||||
if (mMainResearchLog != null) {
|
if (mMainResearchLog != null) {
|
||||||
mMainResearchLog.stop();
|
mMainResearchLog.stop();
|
||||||
}
|
}
|
||||||
|
@ -337,26 +305,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_STATISTICS = {
|
|
||||||
"Statistics", "charCount", "letterCount", "numberCount", "spaceCount", "deleteOpsCount",
|
|
||||||
"wordCount", "isEmptyUponStarting", "isEmptinessStateKnown", "averageTimeBetweenKeys",
|
|
||||||
"averageTimeBeforeDelete", "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete"
|
|
||||||
};
|
|
||||||
private static void logStatistics() {
|
|
||||||
final ResearchLogger researchLogger = getInstance();
|
|
||||||
final Statistics statistics = researchLogger.mStatistics;
|
|
||||||
final Object[] values = {
|
|
||||||
statistics.mCharCount, statistics.mLetterCount, statistics.mNumberCount,
|
|
||||||
statistics.mSpaceCount, statistics.mDeleteKeyCount,
|
|
||||||
statistics.mWordCount, statistics.mIsEmptyUponStarting,
|
|
||||||
statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(),
|
|
||||||
statistics.mBeforeDeleteKeyCounter.getAverageTime(),
|
|
||||||
statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(),
|
|
||||||
statistics.mAfterDeleteKeyCounter.getAverageTime()
|
|
||||||
};
|
|
||||||
researchLogger.enqueueEvent(EVENTKEYS_STATISTICS, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setLoggingAllowed(boolean enableLogging) {
|
private void setLoggingAllowed(boolean enableLogging) {
|
||||||
if (mPrefs == null) {
|
if (mPrefs == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -757,7 +705,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
mLoggingFrequencyState.onWordLogged();
|
mLoggingFrequencyState.onWordLogged();
|
||||||
}
|
}
|
||||||
mCurrentLogUnit = new LogUnit();
|
mCurrentLogUnit = new LogUnit();
|
||||||
mStatistics.recordWordEntered();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishLogUnit(LogUnit logUnit, boolean isPrivacySensitive) {
|
private void publishLogUnit(LogUnit logUnit, boolean isPrivacySensitive) {
|
||||||
|
@ -952,9 +899,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
|
||||||
final Object[] values = {
|
final Object[] values = {
|
||||||
Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
|
Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
|
||||||
};
|
};
|
||||||
final ResearchLogger researchLogger = getInstance();
|
getInstance().enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
|
||||||
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
|
|
||||||
researchLogger.mStatistics.recordChar(code, SystemClock.uptimeMillis());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
|
private static final String[] EVENTKEYS_LATINIME_ONDISPLAYCOMPLETIONS = {
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2012 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
* use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
* the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.inputmethod.research;
|
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Keyboard;
|
|
||||||
|
|
||||||
public class Statistics {
|
|
||||||
// Number of characters entered during a typing session
|
|
||||||
int mCharCount;
|
|
||||||
// Number of letter characters entered during a typing session
|
|
||||||
int mLetterCount;
|
|
||||||
// Number of number characters entered
|
|
||||||
int mNumberCount;
|
|
||||||
// Number of space characters entered
|
|
||||||
int mSpaceCount;
|
|
||||||
// Number of delete operations entered (taps on the backspace key)
|
|
||||||
int mDeleteKeyCount;
|
|
||||||
// Number of words entered during a session.
|
|
||||||
int mWordCount;
|
|
||||||
// Whether the text field was empty upon editing
|
|
||||||
boolean mIsEmptyUponStarting;
|
|
||||||
boolean mIsEmptinessStateKnown;
|
|
||||||
|
|
||||||
// Timers to count average time to enter a key, first press a delete key,
|
|
||||||
// between delete keys, and then to return typing after a delete key.
|
|
||||||
final AverageTimeCounter mKeyCounter = new AverageTimeCounter();
|
|
||||||
final AverageTimeCounter mBeforeDeleteKeyCounter = new AverageTimeCounter();
|
|
||||||
final AverageTimeCounter mDuringRepeatedDeleteKeysCounter = new AverageTimeCounter();
|
|
||||||
final AverageTimeCounter mAfterDeleteKeyCounter = new AverageTimeCounter();
|
|
||||||
|
|
||||||
static class AverageTimeCounter {
|
|
||||||
int mCount;
|
|
||||||
int mTotalTime;
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
mCount = 0;
|
|
||||||
mTotalTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(long deltaTime) {
|
|
||||||
mCount++;
|
|
||||||
mTotalTime += deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAverageTime() {
|
|
||||||
if (mCount == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mTotalTime / mCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To account for the interruptions when the user's attention is directed elsewhere, times
|
|
||||||
// longer than MIN_TYPING_INTERMISSION are not counted when estimating this statistic.
|
|
||||||
public static final int MIN_TYPING_INTERMISSION = 5 * 1000; // in milliseconds
|
|
||||||
public static final int MIN_DELETION_INTERMISSION = 15 * 1000; // in milliseconds
|
|
||||||
|
|
||||||
// The last time that a tap was performed
|
|
||||||
private long mLastTapTime;
|
|
||||||
// The type of the last keypress (delete key or not)
|
|
||||||
boolean mIsLastKeyDeleteKey;
|
|
||||||
|
|
||||||
private static final Statistics sInstance = new Statistics();
|
|
||||||
|
|
||||||
public static Statistics getInstance() {
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Statistics() {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
mCharCount = 0;
|
|
||||||
mLetterCount = 0;
|
|
||||||
mNumberCount = 0;
|
|
||||||
mSpaceCount = 0;
|
|
||||||
mDeleteKeyCount = 0;
|
|
||||||
mWordCount = 0;
|
|
||||||
mIsEmptyUponStarting = true;
|
|
||||||
mIsEmptinessStateKnown = false;
|
|
||||||
mKeyCounter.reset();
|
|
||||||
mBeforeDeleteKeyCounter.reset();
|
|
||||||
mDuringRepeatedDeleteKeysCounter.reset();
|
|
||||||
mAfterDeleteKeyCounter.reset();
|
|
||||||
|
|
||||||
mLastTapTime = 0;
|
|
||||||
mIsLastKeyDeleteKey = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recordChar(int codePoint, long time) {
|
|
||||||
final long delta = time - mLastTapTime;
|
|
||||||
if (codePoint == Keyboard.CODE_DELETE) {
|
|
||||||
mDeleteKeyCount++;
|
|
||||||
if (delta < MIN_DELETION_INTERMISSION) {
|
|
||||||
if (mIsLastKeyDeleteKey) {
|
|
||||||
mDuringRepeatedDeleteKeysCounter.add(delta);
|
|
||||||
} else {
|
|
||||||
mBeforeDeleteKeyCounter.add(delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mIsLastKeyDeleteKey = true;
|
|
||||||
} else {
|
|
||||||
mCharCount++;
|
|
||||||
if (Character.isDigit(codePoint)) {
|
|
||||||
mNumberCount++;
|
|
||||||
}
|
|
||||||
if (Character.isLetter(codePoint)) {
|
|
||||||
mLetterCount++;
|
|
||||||
}
|
|
||||||
if (Character.isSpaceChar(codePoint)) {
|
|
||||||
mSpaceCount++;
|
|
||||||
}
|
|
||||||
if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) {
|
|
||||||
mAfterDeleteKeyCounter.add(delta);
|
|
||||||
} else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) {
|
|
||||||
mKeyCounter.add(delta);
|
|
||||||
}
|
|
||||||
mIsLastKeyDeleteKey = false;
|
|
||||||
}
|
|
||||||
mLastTapTime = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recordWordEntered() {
|
|
||||||
mWordCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsEmptyUponStarting(final boolean isEmpty) {
|
|
||||||
mIsEmptyUponStarting = isEmpty;
|
|
||||||
mIsEmptinessStateKnown = true;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue