Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2009 Google Inc.
      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.latin;
     18 
     19 import com.android.inputmethod.voice.SettingsUtil;
     20 
     21 import android.content.ContentResolver;
     22 import android.content.Context;
     23 import android.content.SharedPreferences;
     24 import android.preference.PreferenceManager;
     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 TAG = "Hints";
     40     private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN =
     41             "voice_hint_num_unique_days_shown";
     42     private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN =
     43             "voice_hint_last_time_shown";
     44     private static final String PREF_VOICE_INPUT_LAST_TIME_USED =
     45             "voice_input_last_time_used";
     46     private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT =
     47             "voice_punctuation_hint_view_count";
     48     private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7;
     49     private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7;
     50 
     51     private Context mContext;
     52     private 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, Display display) {
     67         mContext = context;
     68         mDisplay = display;
     69 
     70         ContentResolver cr = mContext.getContentResolver();
     71         mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt(
     72                 cr,
     73                 SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS,
     74                 DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW);
     75         mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt(
     76                 cr,
     77                 SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS,
     78                 DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS);
     79     }
     80 
     81     public boolean showSwipeHintIfNecessary(boolean fieldRecommended) {
     82         if (fieldRecommended && shouldShowSwipeHint()) {
     83             showHint(R.layout.voice_swipe_hint);
     84             return true;
     85         }
     86 
     87         return false;
     88     }
     89 
     90     public boolean showPunctuationHintIfNecessary(InputConnection ic) {
     91         if (!mVoiceResultContainedPunctuation
     92                 && ic != null
     93                 && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT)
     94                         < mPunctuationHintMaxDisplays) {
     95             CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0);
     96             if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) {
     97                 showHint(R.layout.voice_punctuation_hint);
     98                 return true;
     99             }
    100         }
    101 
    102         return false;
    103     }
    104 
    105     public void registerVoiceResult(String text) {
    106         // Update the current time as the last time voice input was used.
    107         SharedPreferences.Editor editor =
    108                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
    109         editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis());
    110         editor.commit();
    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         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    123 
    124         int numUniqueDaysShown = sp.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 = sp.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         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    161 
    162         int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
    163         long lastTimeHintWasShown = sp.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 = sp.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             editor.commit();
    173         }
    174 
    175         if (mDisplay != null) {
    176             mDisplay.showHint(hintViewResource);
    177         }
    178     }
    179 
    180     private int getAndIncrementPref(String pref) {
    181         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
    182         int value = sp.getInt(pref, 0);
    183         SharedPreferences.Editor editor = sp.edit();
    184         editor.putInt(pref, value + 1);
    185         editor.commit();
    186         return value;
    187     }
    188 }
    189