Home | History | Annotate | Download | only in research
      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