/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.android.inputmethod.deprecated.voice; import com.android.inputmethod.compat.SharedPreferencesCompat; import com.sugree.inputmethod.latin.R; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.view.inputmethod.InputConnection; import java.util.Calendar; import java.util.HashMap; import java.util.Map; /** * Logic to determine when to display hints on usage to the user. */ public class Hints { public interface Display { public void showHint(int viewResource); } private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN = "voice_hint_num_unique_days_shown"; private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN = "voice_hint_last_time_shown"; private static final String PREF_VOICE_INPUT_LAST_TIME_USED = "voice_input_last_time_used"; private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT = "voice_punctuation_hint_view_count"; private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7; private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7; private final Context mContext; private final SharedPreferences mPrefs; private final Display mDisplay; private boolean mVoiceResultContainedPunctuation; private int mSwipeHintMaxDaysToShow; private int mPunctuationHintMaxDisplays; // Only show punctuation hint if voice result did not contain punctuation. static final Map<CharSequence, String> SPEAKABLE_PUNCTUATION = new HashMap<CharSequence, String>(); static { SPEAKABLE_PUNCTUATION.put(",", "comma"); SPEAKABLE_PUNCTUATION.put(".", "period"); SPEAKABLE_PUNCTUATION.put("?", "question mark"); } public Hints(Context context, SharedPreferences prefs, Display display) { mContext = context; mPrefs = prefs; mDisplay = display; ContentResolver cr = mContext.getContentResolver(); mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt( cr, SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS, DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW); mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt( cr, SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS, DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS); } public boolean showSwipeHintIfNecessary(boolean fieldRecommended) { if (fieldRecommended && shouldShowSwipeHint()) { showHint(R.layout.voice_swipe_hint); return true; } return false; } public boolean showPunctuationHintIfNecessary(InputConnection ic) { if (!mVoiceResultContainedPunctuation && ic != null && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT) < mPunctuationHintMaxDisplays) { CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0); if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) { showHint(R.layout.voice_punctuation_hint); return true; } } return false; } public void registerVoiceResult(String text) { // Update the current time as the last time voice input was used. SharedPreferences.Editor editor = mPrefs.edit(); editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis()); SharedPreferencesCompat.apply(editor); mVoiceResultContainedPunctuation = false; for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) { if (text.indexOf(s.toString()) >= 0) { mVoiceResultContainedPunctuation = true; break; } } } private boolean shouldShowSwipeHint() { final SharedPreferences prefs = mPrefs; int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); // If we've already shown the hint for enough days, we'll return false. if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) { long lastTimeVoiceWasUsed = prefs.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0); // If the user has used voice today, we'll return false. (We don't show the hint on // any day that the user has already used voice.) if (!isFromToday(lastTimeVoiceWasUsed)) { return true; } } return false; } /** * Determines whether the provided time is from some time today (i.e., this day, month, * and year). */ private boolean isFromToday(long timeInMillis) { if (timeInMillis == 0) return false; Calendar today = Calendar.getInstance(); today.setTimeInMillis(System.currentTimeMillis()); Calendar timestamp = Calendar.getInstance(); timestamp.setTimeInMillis(timeInMillis); return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) && today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) && today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH)); } private void showHint(int hintViewResource) { final SharedPreferences prefs = mPrefs; int numUniqueDaysShown = prefs.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); long lastTimeHintWasShown = prefs.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0); // If this is the first time the hint is being shown today, increase the saved values // to represent that. We don't need to increase the last time the hint was shown unless // it is a different day from the current value. if (!isFromToday(lastTimeHintWasShown)) { SharedPreferences.Editor editor = prefs.edit(); editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1); editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis()); SharedPreferencesCompat.apply(editor); } if (mDisplay != null) { mDisplay.showHint(hintViewResource); } } private int getAndIncrementPref(String pref) { final SharedPreferences prefs = mPrefs; int value = prefs.getInt(pref, 0); SharedPreferences.Editor editor = prefs.edit(); editor.putInt(pref, value + 1); SharedPreferencesCompat.apply(editor); return value; } }