PageRenderTime 13ms CodeModel.GetById 2ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/Hints.java

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