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