Config.java revision 7a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24
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.AlarmManager; 20import android.content.Context; 21import android.os.Process; 22import android.util.Log; 23 24import java.util.HashSet; 25 26/** 27 * Provides values for configurable parameters in all of QSB. 28 * 29 * All the methods in this class return fixed default values. Subclasses may 30 * make these values server-side settable. 31 * 32 */ 33public class Config { 34 35 private static final String TAG = "QSB.Config"; 36 private static final boolean DBG = false; 37 38 protected static final long SECOND_MILLIS = 1000L; 39 protected static final long MINUTE_MILLIS = 60L * SECOND_MILLIS; 40 protected static final long DAY_MILLIS = 86400000L; 41 42 private static final int NUM_PROMOTED_SOURCES = 3; 43 private static final int MAX_PROMOTED_SUGGESTIONS = 8; 44 private static final int MAX_RESULTS_PER_SOURCE = 50; 45 private static final int MAX_SHORTCUTS_PER_WEB_SOURCE = MAX_PROMOTED_SUGGESTIONS; 46 private static final int MAX_SHORTCUTS_PER_NON_WEB_SOURCE = 2; 47 private static final long SOURCE_TIMEOUT_MILLIS = 10000; 48 49 private static final int QUERY_THREAD_PRIORITY = 50 Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE; 51 52 private static final long MAX_STAT_AGE_MILLIS = 30 * DAY_MILLIS; 53 private static final int MIN_CLICKS_FOR_SOURCE_RANKING = 3; 54 55 private static final int NUM_WEB_CORPUS_THREADS = 2; 56 57 private static final int LATENCY_LOG_FREQUENCY = 1000; 58 59 private static final long TYPING_SUGGESTIONS_UPDATE_DELAY_MILLIS = 100; 60 private static final long PUBLISH_RESULT_DELAY_MILLIS = 200; 61 62 private static final long VOICE_SEARCH_HINT_ACTIVE_PERIOD = 7L * DAY_MILLIS; 63 64 private static final long VOICE_SEARCH_HINT_UPDATE_INTERVAL 65 = AlarmManager.INTERVAL_FIFTEEN_MINUTES; 66 67 private static final long VOICE_SEARCH_HINT_SHOW_PERIOD_MILLIS 68 = AlarmManager.INTERVAL_HOUR * 2; 69 70 private static final long VOICE_SEARCH_HINT_CHANGE_PERIOD = 2L * MINUTE_MILLIS; 71 72 private static final long VOICE_SEARCH_HINT_VISIBLE_PERIOD = 6L * MINUTE_MILLIS; 73 74 private final Context mContext; 75 private HashSet<String> mDefaultCorpora; 76 private HashSet<String> mHiddenCorpora; 77 private HashSet<String> mDefaultCorporaSuggestUris; 78 79 /** 80 * Creates a new config that uses hard-coded default values. 81 */ 82 public Config(Context context) { 83 mContext = context; 84 } 85 86 protected Context getContext() { 87 return mContext; 88 } 89 90 /** 91 * Releases any resources used by the configuration object. 92 * 93 * Default implementation does nothing. 94 */ 95 public void close() { 96 } 97 98 private HashSet<String> loadResourceStringSet(int res) { 99 HashSet<String> defaultCorpora = new HashSet<String>(); 100 String[] corpora = mContext.getResources().getStringArray(res); 101 for (String corpus : corpora) { 102 if (DBG) Log.d(TAG, "Default corpus: " + corpus); 103 defaultCorpora.add(corpus); 104 } 105 return defaultCorpora; 106 } 107 108 /** 109 * Checks if we trust the given source not to be spammy. 110 */ 111 public synchronized boolean isCorpusEnabledByDefault(Corpus corpus) { 112 if (DBG) Log.d(TAG, "isCorpusEnabledByDefault(" + corpus.getName() + ")"); 113 if (mDefaultCorpora == null) { 114 mDefaultCorpora = loadResourceStringSet(R.array.default_corpora); 115 } 116 if (mDefaultCorpora.contains(corpus.getName())) { 117 if (DBG) Log.d(TAG, "Corpus " + corpus.getName() + " IS default"); 118 return true; 119 } 120 121 if (mDefaultCorporaSuggestUris == null) { 122 mDefaultCorporaSuggestUris = loadResourceStringSet( 123 R.array.default_corpora_suggest_uris); 124 } 125 126 for (Source s : corpus.getSources()) { 127 String uri = s.getSuggestUri(); 128 if (DBG) Log.d(TAG, "Suggest URI for " + corpus.getName() + ": " + uri); 129 if (mDefaultCorporaSuggestUris.contains(uri)) { 130 if (DBG) Log.d(TAG, "Corpus " + corpus.getName() + " IS default"); 131 return true; 132 } 133 } 134 if (DBG) Log.d(TAG, "Corpus " + corpus.getName() + " is NOT default"); 135 return false; 136 } 137 138 /** 139 * Checks if the given corpus should be hidden from the corpus selection dialog. 140 */ 141 public synchronized boolean isCorpusHidden(String corpusName) { 142 if (mHiddenCorpora == null) { 143 mHiddenCorpora = loadResourceStringSet(R.array.hidden_corpora); 144 } 145 return mHiddenCorpora.contains(corpusName); 146 } 147 148 /** 149 * The number of promoted sources. 150 */ 151 public int getNumPromotedSources() { 152 return NUM_PROMOTED_SOURCES; 153 } 154 155 /** 156 * The number of suggestions visible above the onscreen keyboard. 157 */ 158 public int getNumSuggestionsAboveKeyboard() { 159 // Get the list of default corpora from a resource, which allows vendor overlays. 160 return mContext.getResources().getInteger(R.integer.num_suggestions_above_keyboard); 161 } 162 163 /** 164 * The maximum number of suggestions to promote. 165 */ 166 public int getMaxPromotedSuggestions() { 167 return mContext.getResources().getInteger(R.integer.max_promoted_suggestions); 168 } 169 170 public int getMaxPromotedResults() { 171 return mContext.getResources().getInteger(R.integer.max_promoted_results); 172 } 173 174 /** 175 * The number of results to ask each source for. 176 */ 177 public int getMaxResultsPerSource() { 178 return MAX_RESULTS_PER_SOURCE; 179 } 180 181 /** 182 * The maximum number of shortcuts to show for the web source in All mode. 183 */ 184 public int getMaxShortcutsPerWebSource() { 185 return MAX_SHORTCUTS_PER_WEB_SOURCE; 186 } 187 188 /** 189 * The maximum number of shortcuts to show for each non-web source in All mode. 190 */ 191 public int getMaxShortcutsPerNonWebSource() { 192 return MAX_SHORTCUTS_PER_NON_WEB_SOURCE; 193 } 194 195 /** 196 * Gets the maximum number of shortcuts that will be shown from the given source. 197 */ 198 public int getMaxShortcuts(String sourceName) { 199 return getMaxShortcutsPerNonWebSource(); 200 } 201 202 /** 203 * The timeout for querying each source, in milliseconds. 204 */ 205 public long getSourceTimeoutMillis() { 206 return SOURCE_TIMEOUT_MILLIS; 207 } 208 209 /** 210 * The priority of query threads. 211 * 212 * @return A thread priority, as defined in {@link Process}. 213 */ 214 public int getQueryThreadPriority() { 215 return QUERY_THREAD_PRIORITY; 216 } 217 218 /** 219 * The maximum age of log data used for shortcuts. 220 */ 221 public long getMaxStatAgeMillis(){ 222 return MAX_STAT_AGE_MILLIS; 223 } 224 225 /** 226 * The minimum number of clicks needed to rank a source. 227 */ 228 public int getMinClicksForSourceRanking(){ 229 return MIN_CLICKS_FOR_SOURCE_RANKING; 230 } 231 232 public int getNumWebCorpusThreads() { 233 return NUM_WEB_CORPUS_THREADS; 234 } 235 236 /** 237 * How often query latency should be logged. 238 * 239 * @return An integer in the range 0-1000. 0 means that no latency events 240 * should be logged. 1000 means that all latency events should be logged. 241 */ 242 public int getLatencyLogFrequency() { 243 return LATENCY_LOG_FREQUENCY; 244 } 245 246 /** 247 * The delay in milliseconds before suggestions are updated while typing. 248 * If a new character is typed before this timeout expires, the timeout is reset. 249 */ 250 public long getTypingUpdateSuggestionsDelayMillis() { 251 return TYPING_SUGGESTIONS_UPDATE_DELAY_MILLIS; 252 } 253 254 /** 255 * The delay in milliseconds before corpus results are published. 256 * If a new result arrives before this timeout expires, the timeout is reset. 257 */ 258 public long getPublishResultDelayMillis() { 259 return PUBLISH_RESULT_DELAY_MILLIS; 260 } 261 262 public boolean allowVoiceSearchHints() { 263 return true; 264 } 265 266 /** 267 * The period of time for which after installing voice search we should consider showing voice 268 * search hints. 269 * 270 * @return The period in milliseconds. 271 */ 272 public long getVoiceSearchHintActivePeriod() { 273 return VOICE_SEARCH_HINT_ACTIVE_PERIOD; 274 } 275 276 /** 277 * The time interval at which we should consider whether or not to show some voice search hints. 278 * 279 * @return The period in milliseconds. 280 */ 281 public long getVoiceSearchHintUpdatePeriod() { 282 return VOICE_SEARCH_HINT_UPDATE_INTERVAL; 283 } 284 285 /** 286 * The time interval at which, on average, voice search hints are displayed. 287 * 288 * @return The period in milliseconds. 289 */ 290 public long getVoiceSearchHintShowPeriod() { 291 return VOICE_SEARCH_HINT_SHOW_PERIOD_MILLIS; 292 } 293 294 /** 295 * The amount of time for which voice search hints are displayed in one go. 296 * 297 * @return The period in milliseconds. 298 */ 299 public long getVoiceSearchHintVisibleTime() { 300 return VOICE_SEARCH_HINT_VISIBLE_PERIOD; 301 } 302 303 /** 304 * The period that we change voice search hints at while they're being displayed. 305 * 306 * @return The period in milliseconds. 307 */ 308 public long getVoiceSearchHintChangePeriod() { 309 return VOICE_SEARCH_HINT_CHANGE_PERIOD; 310 } 311 312 public boolean showSuggestionsForZeroQuery() { 313 // Get the list of default corpora from a resource, which allows vendor overlays. 314 return mContext.getResources().getBoolean(R.bool.show_zero_query_suggestions); 315 } 316 317 public boolean showShortcutsForZeroQuery() { 318 // Get the list of default corpora from a resource, which allows vendor overlays. 319 return mContext.getResources().getBoolean(R.bool.show_zero_query_shortcuts); 320 } 321 322 public boolean showScrollingSuggestions() { 323 return mContext.getResources().getBoolean(R.bool.show_scrolling_suggestions); 324 } 325 326 public boolean showScrollingResults() { 327 return mContext.getResources().getBoolean(R.bool.show_scrolling_results); 328 } 329 330} 331