/*
* 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;
}
}