Home | History | Annotate | Download | only in voice
      1 /*
      2  * Copyright (C) 2009 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.deprecated.voice;
     18 
     19 import com.android.inputmethod.compat.SharedPreferencesCompat;
     20 import com.android.inputmethod.latin.R;
     21 
     22 import android.content.ContentResolver;
     23 import android.content.Context;
     24 import android.content.SharedPreferences;
     25 import android.view.inputmethod.InputConnection;
     26 
     27 import java.util.Calendar;
     28 import java.util.HashMap;
     29 import java.util.Map;
     30 
     31 /**
     32  * Logic to determine when to display hints on usage to the user.
     33  */
     34 public class Hints {
     35     public interface Display {
     36         public void showHint(int viewResource);
     37     }
     38 
     39     private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN =
     40             "voice_hint_num_unique_days_shown";
     41     private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN =
     42             "voice_hint_last_time_shown";
     43     private static final String PREF_VOICE_INPUT_LAST_TIME_USED =
     44             "voice_input_last_time_used";
     45     private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT =
     46             "voice_punctuation_hint_view_count";
     47     private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7;
     48     private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7;
     49 
     50     private final Context mContext;
     51     private final SharedPreferences mPrefs;
     52     private final Display mDisplay;
     53     private boolean mVoiceResultContainedPunctuation;
     54     private int mSwipeHintMaxDaysToShow;
     55     private int mPunctuationHintMaxDisplays;
     56 
     57     // Only show punctuation hint if voice result did not contain punctuation.
     58     static final Map<CharSequence, String> SPEAKABLE_PUNCTUATION
     59             = new HashMap<CharSequence, String>();
     60     static {
     61         SPEAKABLE_PUNCTUATION.put(",", "comma");
     62         SPEAKABLE_PUNCTUATION.put(".", "period");
     63         SPEAKABLE_PUNCTUATION.put("?", "question mark");
     64     }
     65 
     66     public Hints(Context context, SharedPreferences prefs, Display display) {
     67         mContext = context;
     68         mPrefs = prefs;
     69         mDisplay = display;
     70 
     71         ContentResolver cr = mContext.getContentResolver();
     72         mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt(
     73                 cr,
     74                 SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS,
     75                 DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW);
     76         mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt(
     77                 cr,
     78                 SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS,
     79                 DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS);
     80     }
     81 
     82     public boolean showSwipeHintIfNecessary(boolean fieldRecommended) {
     83         if (fieldRecommended && shouldShowSwipeHint()) {
     84             showHint(R.layout.voice_swipe_hint);
     85             return true;
     86         }
     87 
     88         return false;
     89     }
     90 
     91     public boolean showPunctuationHintIfNecessary(InputConnection ic) {
     92         if (!mVoiceResultContainedPunctuation
     93                 && ic != null
     94                 && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT)
     95                         < mPunctuationHintMaxDisplays) {
     96             CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0);
     97             if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) {
     98                 showHint(R.layout.voice_punctuation_hint);
     99                 return true;
    100             }
    101         }
    102 
    103         return false;
    104     }
    105 
    106     public void registerVoiceResult(String text) {
    107         // Update the current time as the last time voice input was used.
    108         SharedPreferences.Editor editor = mPrefs.edit();
    109         editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis());
    110         SharedPreferencesCompat.apply(editor);
    111 
    112         mVoiceResultContainedPunctuation = false;
    113         for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) {
    114             if (text.indexOf(s.toString()) >= 0) {
    115                 mVoiceResultContainedPunctuation = true;
    116                 break;
    117             }
    118         }
    119     }
    120 
    121     private boolean shouldShowSwipeHint() {
    122         final SharedPreferences prefs = mPrefs;
    123 
    124         int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
    125 
    126         // If we've already shown the hint for enough days, we'll return false.
    127         if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) {
    128 
    129             long lastTimeVoiceWasUsed = prefs.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0);
    130 
    131             // If the user has used voice today, we'll return false. (We don't show the hint on
    132             // any day that the user has already used voice.)
    133             if (!isFromToday(lastTimeVoiceWasUsed)) {
    134                 return true;
    135             }
    136         }
    137 
    138         return false;
    139     }
    140 
    141     /**
    142      * Determines whether the provided time is from some time today (i.e., this day, month,
    143      * and year).
    144      */
    145     private boolean isFromToday(long timeInMillis) {
    146         if (timeInMillis == 0) return false;
    147 
    148         Calendar today = Calendar.getInstance();
    149         today.setTimeInMillis(System.currentTimeMillis());
    150 
    151         Calendar timestamp = Calendar.getInstance();
    152         timestamp.setTimeInMillis(timeInMillis);
    153 
    154         return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) &&
    155                 today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) &&
    156                 today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH));
    157     }
    158 
    159     private void showHint(int hintViewResource) {
    160         final SharedPreferences prefs = mPrefs;
    161 
    162         int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
    163         long lastTimeHintWasShown = prefs.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0);
    164 
    165         // If this is the first time the hint is being shown today, increase the saved values
    166         // to represent that. We don't need to increase the last time the hint was shown unless
    167         // it is a different day from the current value.
    168         if (!isFromToday(lastTimeHintWasShown)) {
    169             SharedPreferences.Editor editor = prefs.edit();
    170             editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1);
    171             editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis());
    172             SharedPreferencesCompat.apply(editor);
    173         }
    174 
    175         if (mDisplay != null) {
    176             mDisplay.showHint(hintViewResource);
    177         }
    178     }
    179 
    180     private int getAndIncrementPref(String pref) {
    181         final SharedPreferences prefs = mPrefs;
    182         int value = prefs.getInt(pref, 0);
    183         SharedPreferences.Editor editor = prefs.edit();
    184         editor.putInt(pref, value + 1);
    185         SharedPreferencesCompat.apply(editor);
    186         return value;
    187     }
    188 }
    189