• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
reset()49         public void reset() {
50             mCount = 0;
51             mTotalTime = 0;
52         }
53 
add(long deltaTime)54         public void add(long deltaTime) {
55             mCount++;
56             mTotalTime += deltaTime;
57         }
58 
getAverageTime()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 
getInstance()79     public static Statistics getInstance() {
80         return sInstance;
81     }
82 
Statistics()83     private Statistics() {
84         reset();
85     }
86 
reset()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 
recordChar(int codePoint, long time)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 
recordWordEntered()138     public void recordWordEntered() {
139         mWordCount++;
140     }
141 
setIsEmptyUponStarting(final boolean isEmpty)142     public void setIsEmptyUponStarting(final boolean isEmpty) {
143         mIsEmptyUponStarting = isEmpty;
144         mIsEmptinessStateKnown = true;
145     }
146 }
147