Config.java revision 39bbcdc1a485ded93059de4a3f70bfda85e9f304
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.content.Context;
20import android.content.res.Resources;
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
37    private static final long DAY_MILLIS = 86400000L;
38
39    private static final int NUM_SUGGESTIONS_ABOVE_KEYBOARD = 4;
40    private static final int NUM_PROMOTED_SOURCES = 3;
41    private static final int MAX_PROMOTED_SUGGESTIONS = 8;
42    private static final int MAX_RESULTS_PER_SOURCE = 50;
43    private static final long SOURCE_TIMEOUT_MILLIS = 10000;
44
45    private static final int QUERY_THREAD_MAX_POOL_SIZE = 4;
46    private static final long QUERY_THREAD_KEEPALIVE_MILLIS = 30000;
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 = 7 * DAY_MILLIS;
51    private static final long MAX_SOURCE_EVENT_AGE_MILLIS = 30 * DAY_MILLIS;
52    private static final int MIN_IMPRESSIONS_FOR_SOURCE_RANKING = 5;
53    private static final int MIN_CLICKS_FOR_SOURCE_RANKING = 3;
54    private static final int MAX_SHORTCUTS_RETURNED = MAX_PROMOTED_SUGGESTIONS;
55
56    private static final long THREAD_START_DELAY_MILLIS = 100;
57
58    private static final int NUM_WEB_CORPUS_THREADS = 2;
59
60    private static final int LATENCY_LOG_FREQUENCY = 1000;
61
62    private static final long TYPING_SUGGESTIONS_UPDATE_DELAY_MILLIS = 100;
63
64    private final Context mContext;
65    private HashSet<String> mDefaultCorpora;
66
67    /**
68     * Creates a new config that uses hard-coded default values.
69     */
70    public Config(Context context) {
71        mContext = context;
72    }
73
74    protected Context getContext() {
75        return mContext;
76    }
77
78    /**
79     * Releases any resources used by the configuration object.
80     *
81     * Default implementation does nothing.
82     */
83    public void close() {
84    }
85
86    private HashSet<String> loadDefaultCorpora() {
87        HashSet<String> defaultCorpora = new HashSet<String>();
88        try {
89            // Get the list of default corpora from a resource, which allows vendor overlays.
90            String[] corpora = mContext.getResources().getStringArray(R.array.default_corpora);
91            for (String corpus : corpora) {
92                defaultCorpora.add(corpus);
93            }
94            return defaultCorpora;
95        } catch (Resources.NotFoundException ex) {
96            Log.e(TAG, "Could not load default corpora", ex);
97            return defaultCorpora;
98        }
99    }
100
101    /**
102     * Checks if we trust the given source not to be spammy.
103     */
104    public synchronized boolean isCorpusEnabledByDefault(String corpusName) {
105        if (mDefaultCorpora == null) {
106            mDefaultCorpora = loadDefaultCorpora();
107        }
108        return mDefaultCorpora.contains(corpusName);
109    }
110
111    /**
112     * The number of promoted sources.
113     */
114    public int getNumPromotedSources() {
115        return NUM_PROMOTED_SOURCES;
116    }
117
118    /**
119     * The number of suggestions visible above the onscreen keyboard.
120     */
121    public int getNumSuggestionsAboveKeyboard() {
122        try {
123            // Get the list of default corpora from a resource, which allows vendor overlays.
124            return mContext.getResources().getInteger(R.integer.num_suggestions_above_keyboard);
125        } catch (Resources.NotFoundException ex) {
126            Log.e(TAG, "Could not load num_suggestions_above_keyboard", ex);
127            return NUM_SUGGESTIONS_ABOVE_KEYBOARD;
128        }
129    }
130
131    /**
132     * The maximum number of suggestions to promote.
133     */
134    public int getMaxPromotedSuggestions() {
135        return MAX_PROMOTED_SUGGESTIONS;
136    }
137
138    /**
139     * The number of results to ask each source for.
140     */
141    public int getMaxResultsPerSource() {
142        return MAX_RESULTS_PER_SOURCE;
143    }
144
145    /**
146     * The timeout for querying each source, in milliseconds.
147     */
148    public long getSourceTimeoutMillis() {
149        return SOURCE_TIMEOUT_MILLIS;
150    }
151
152    /**
153     * The maximum thread pool size for the query thread pool.
154     */
155    public int getQueryThreadMaxPoolSize(){
156        return QUERY_THREAD_MAX_POOL_SIZE;
157    }
158
159    /**
160     * The keep-alive time for the query thread pool, in millisseconds.
161     */
162    public long getQueryThreadKeepAliveMillis() {
163        return QUERY_THREAD_KEEPALIVE_MILLIS;
164    }
165
166    /**
167     * The priority of query threads.
168     *
169     * @return A thread priority, as defined in {@link Process}.
170     */
171    public int getQueryThreadPriority() {
172        return QUERY_THREAD_PRIORITY;
173    }
174
175    /**
176     * The maximum age of log data used for shortcuts.
177     */
178    public long getMaxStatAgeMillis(){
179        return MAX_STAT_AGE_MILLIS;
180    }
181
182    /**
183     * The maximum age of log data used for source ranking.
184     */
185    public long getMaxSourceEventAgeMillis(){
186        return MAX_SOURCE_EVENT_AGE_MILLIS;
187    }
188
189    /**
190     * The minimum number of impressions needed to rank a source.
191     */
192    public int getMinImpressionsForSourceRanking(){
193        return MIN_IMPRESSIONS_FOR_SOURCE_RANKING;
194    }
195
196    /**
197     * The minimum number of clicks needed to rank a source.
198     */
199    public int getMinClicksForSourceRanking(){
200        return MIN_CLICKS_FOR_SOURCE_RANKING;
201    }
202
203    /**
204     * The maximum number of shortcuts shown.
205     */
206    public int getMaxShortcutsReturned(){
207        return MAX_SHORTCUTS_RETURNED;
208    }
209
210    /**
211     * The maximum time to delay starting a search query thread after the user types a character.
212     */
213    public long getThreadStartDelayMillis() {
214        return THREAD_START_DELAY_MILLIS;
215    }
216
217    public int getNumWebCorpusThreads() {
218        return NUM_WEB_CORPUS_THREADS;
219    }
220
221    /**
222     * How often query latency should be logged.
223     *
224     * @return An integer in the range 0-1000. 0 means that no latency events
225     *         should be logged. 1000 means that all latency events should be logged.
226     */
227    public int getLatencyLogFrequency() {
228        return LATENCY_LOG_FREQUENCY;
229    }
230
231    /**
232     * The delay in milliseconds before suggestions are updated while typing.
233     * If a new character is typed before this timeout expires, the timeout is reset.
234     */
235    public long getTypingUpdateSuggestionsDelayMillis() {
236        return TYPING_SUGGESTIONS_UPDATE_DELAY_MILLIS;
237    }
238}
239