SearchSettingsImpl.java revision d84f30fc2964eded2bf559c06d6d8e77ae26a2d0
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.quicksearchbox; 18 19import com.android.quicksearchbox.util.Compat; 20 21import android.app.SearchManager; 22import android.content.Context; 23import android.content.Intent; 24import android.content.SharedPreferences; 25import android.util.Log; 26import android.view.Menu; 27import android.view.MenuInflater; 28import android.view.MenuItem; 29 30/** 31 * Manages user settings. 32 */ 33public class SearchSettingsImpl implements SearchSettings { 34 35 private static final boolean DBG = false; 36 private static final String TAG = "QSB.SearchSettingsImpl"; 37 38 // Name of the preferences file used to store search preference 39 public static final String PREFERENCES_NAME = "SearchSettings"; 40 41 // Intent action that opens the "Searchable Items" preference 42 private static final String ACTION_SEARCHABLE_ITEMS = 43 "com.android.quicksearchbox.action.SEARCHABLE_ITEMS"; 44 45 /** 46 * Preference key used for storing the index of the next voice search hint to show. 47 */ 48 private static final String NEXT_VOICE_SEARCH_HINT_INDEX_PREF = "next_voice_search_hint"; 49 50 /** 51 * Preference key used to store the time at which the first voice search hint was displayed. 52 */ 53 private static final String FIRST_VOICE_HINT_DISPLAY_TIME = "first_voice_search_hint_time"; 54 55 /** 56 * Preference key for the version of voice search we last got hints from. 57 */ 58 private static final String LAST_SEEN_VOICE_SEARCH_VERSION = "voice_search_version"; 59 60 /** 61 * Prefix of per-corpus enable preference 62 */ 63 private static final String CORPUS_ENABLED_PREF_PREFIX = "enable_corpus_"; 64 65 private final Context mContext; 66 67 private final Config mConfig; 68 69 public SearchSettingsImpl(Context context, Config config) { 70 mContext = context; 71 mConfig = config; 72 } 73 74 protected Context getContext() { 75 return mContext; 76 } 77 78 protected Config getConfig() { 79 return mConfig; 80 } 81 82 public void upgradeSettingsIfNeeded() { 83 } 84 85 public Intent getSearchableItemsIntent() { 86 Intent intent = new Intent(ACTION_SEARCHABLE_ITEMS); 87 intent.setPackage(getContext().getPackageName()); 88 return intent; 89 } 90 91 /** 92 * Gets the preference key of the preference for whether the given corpus 93 * is enabled. The preference is stored in the {@link #PREFERENCES_NAME} 94 * preferences file. 95 */ 96 public static String getCorpusEnabledPreference(Corpus corpus) { 97 return CORPUS_ENABLED_PREF_PREFIX + corpus.getName(); 98 } 99 100 public boolean isCorpusEnabled(Corpus corpus) { 101 boolean defaultEnabled = corpus.isCorpusDefaultEnabled(); 102 String sourceEnabledPref = getCorpusEnabledPreference(corpus); 103 return getSearchPreferences().getBoolean(sourceEnabledPref, defaultEnabled); 104 } 105 106 protected SharedPreferences getSearchPreferences() { 107 return getContext().getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE); 108 } 109 110 protected void storeBoolean(String name, boolean value) { 111 Compat.applyPrefs(getSearchPreferences().edit().putBoolean(name, value)); 112 } 113 114 protected void storeInt(String name, int value) { 115 Compat.applyPrefs(getSearchPreferences().edit().putInt(name, value)); 116 } 117 118 protected void storeLong(String name, long value) { 119 Compat.applyPrefs(getSearchPreferences().edit().putLong(name, value)); 120 } 121 122 protected void storeString(String name, String value) { 123 Compat.applyPrefs(getSearchPreferences().edit().putString(name, value)); 124 } 125 126 protected void removePref(String name) { 127 Compat.applyPrefs(getSearchPreferences().edit().remove(name)); 128 } 129 130 /** 131 * Informs our listeners about the updated settings data. 132 */ 133 public void broadcastSettingsChanged() { 134 // We use a message broadcast since the listeners could be in multiple processes. 135 Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS_CHANGED); 136 Log.i(TAG, "Broadcasting: " + intent); 137 getContext().sendBroadcast(intent); 138 } 139 140 public void addMenuItems(Menu menu, boolean showDisabled) { 141 MenuInflater inflater = new MenuInflater(getContext()); 142 inflater.inflate(R.menu.settings, menu); 143 MenuItem item = menu.findItem(R.id.menu_settings); 144 item.setIntent(getSearchSettingsIntent()); 145 } 146 147 public Intent getSearchSettingsIntent() { 148 Intent settings = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS); 149 settings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 150 settings.setPackage(getContext().getPackageName()); 151 return settings; 152 } 153 154 public int getNextVoiceSearchHintIndex(int size) { 155 int i = getAndIncrementIntPreference(getSearchPreferences(), 156 NEXT_VOICE_SEARCH_HINT_INDEX_PREF); 157 return i % size; 158 } 159 160 // TODO: Could this be made atomic to avoid races? 161 private int getAndIncrementIntPreference(SharedPreferences prefs, String name) { 162 int i = prefs.getInt(name, 0); 163 storeInt(name, i + 1); 164 return i; 165 } 166 167 public void resetVoiceSearchHintFirstSeenTime() { 168 storeLong(FIRST_VOICE_HINT_DISPLAY_TIME, System.currentTimeMillis()); 169 } 170 171 public boolean haveVoiceSearchHintsExpired(int currentVoiceSearchVersion) { 172 SharedPreferences prefs = getSearchPreferences(); 173 174 if (currentVoiceSearchVersion != 0) { 175 long currentTime = System.currentTimeMillis(); 176 int lastVoiceSearchVersion = prefs.getInt(LAST_SEEN_VOICE_SEARCH_VERSION, 0); 177 long firstHintTime = prefs.getLong(FIRST_VOICE_HINT_DISPLAY_TIME, 0); 178 if (firstHintTime == 0 || currentVoiceSearchVersion != lastVoiceSearchVersion) { 179 Compat.applyPrefs(prefs.edit() 180 .putInt(LAST_SEEN_VOICE_SEARCH_VERSION, currentVoiceSearchVersion) 181 .putLong(FIRST_VOICE_HINT_DISPLAY_TIME, currentTime)); 182 firstHintTime = currentTime; 183 } 184 if (currentTime - firstHintTime > getConfig().getVoiceSearchHintActivePeriod()) { 185 if (DBG) Log.d(TAG, "Voice seach hint period expired; not showing hints."); 186 return true; 187 } else { 188 return false; 189 } 190 } else { 191 if (DBG) Log.d(TAG, "Could not determine voice search version; not showing hints."); 192 return true; 193 } 194 } 195 196 public boolean allowWebSearchShortcuts() { 197 return true; 198 } 199 200} 201