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