1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.inputmethod.research; 18 19 import com.android.inputmethod.keyboard.Keyboard; 20 21 public class Statistics { 22 // Number of characters entered during a typing session 23 int mCharCount; 24 // Number of letter characters entered during a typing session 25 int mLetterCount; 26 // Number of number characters entered 27 int mNumberCount; 28 // Number of space characters entered 29 int mSpaceCount; 30 // Number of delete operations entered (taps on the backspace key) 31 int mDeleteKeyCount; 32 // Number of words entered during a session. 33 int mWordCount; 34 // Whether the text field was empty upon editing 35 boolean mIsEmptyUponStarting; 36 boolean mIsEmptinessStateKnown; 37 38 // Timers to count average time to enter a key, first press a delete key, 39 // between delete keys, and then to return typing after a delete key. 40 final AverageTimeCounter mKeyCounter = new AverageTimeCounter(); 41 final AverageTimeCounter mBeforeDeleteKeyCounter = new AverageTimeCounter(); 42 final AverageTimeCounter mDuringRepeatedDeleteKeysCounter = new AverageTimeCounter(); 43 final AverageTimeCounter mAfterDeleteKeyCounter = new AverageTimeCounter(); 44 45 static class AverageTimeCounter { 46 int mCount; 47 int mTotalTime; 48 49 public void reset() { 50 mCount = 0; 51 mTotalTime = 0; 52 } 53 54 public void add(long deltaTime) { 55 mCount++; 56 mTotalTime += deltaTime; 57 } 58 59 public int getAverageTime() { 60 if (mCount == 0) { 61 return 0; 62 } 63 return mTotalTime / mCount; 64 } 65 } 66 67 // To account for the interruptions when the user's attention is directed elsewhere, times 68 // longer than MIN_TYPING_INTERMISSION are not counted when estimating this statistic. 69 public static final int MIN_TYPING_INTERMISSION = 2 * 1000; // in milliseconds 70 public static final int MIN_DELETION_INTERMISSION = 10 * 1000; // in milliseconds 71 72 // The last time that a tap was performed 73 private long mLastTapTime; 74 // The type of the last keypress (delete key or not) 75 boolean mIsLastKeyDeleteKey; 76 77 private static final Statistics sInstance = new Statistics(); 78 79 public static Statistics getInstance() { 80 return sInstance; 81 } 82 83 private Statistics() { 84 reset(); 85 } 86 87 public void reset() { 88 mCharCount = 0; 89 mLetterCount = 0; 90 mNumberCount = 0; 91 mSpaceCount = 0; 92 mDeleteKeyCount = 0; 93 mWordCount = 0; 94 mIsEmptyUponStarting = true; 95 mIsEmptinessStateKnown = false; 96 mKeyCounter.reset(); 97 mBeforeDeleteKeyCounter.reset(); 98 mDuringRepeatedDeleteKeysCounter.reset(); 99 mAfterDeleteKeyCounter.reset(); 100 101 mLastTapTime = 0; 102 mIsLastKeyDeleteKey = false; 103 } 104 105 public void recordChar(int codePoint, long time) { 106 final long delta = time - mLastTapTime; 107 if (codePoint == Keyboard.CODE_DELETE) { 108 mDeleteKeyCount++; 109 if (delta < MIN_DELETION_INTERMISSION) { 110 if (mIsLastKeyDeleteKey) { 111 mDuringRepeatedDeleteKeysCounter.add(delta); 112 } else { 113 mBeforeDeleteKeyCounter.add(delta); 114 } 115 } 116 mIsLastKeyDeleteKey = true; 117 } else { 118 mCharCount++; 119 if (Character.isDigit(codePoint)) { 120 mNumberCount++; 121 } 122 if (Character.isLetter(codePoint)) { 123 mLetterCount++; 124 } 125 if (Character.isSpaceChar(codePoint)) { 126 mSpaceCount++; 127 } 128 if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) { 129 mAfterDeleteKeyCounter.add(delta); 130 } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) { 131 mKeyCounter.add(delta); 132 } 133 mIsLastKeyDeleteKey = false; 134 } 135 mLastTapTime = time; 136 } 137 138 public void recordWordEntered() { 139 mWordCount++; 140 } 141 142 public void setIsEmptyUponStarting(final boolean isEmpty) { 143 mIsEmptyUponStarting = isEmpty; 144 mIsEmptinessStateKnown = true; 145 } 146 } 147