QsbApplication.java revision 21bff9bbf4286907b01d3153bff2fbd6b5ec5df8
13e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/*
23e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Copyright (C) 2009 The Android Open Source Project
33e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert *
43e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
53e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * you may not use this file except in compliance with the License.
63e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * You may obtain a copy of the License at
73e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert *
83e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
93e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert *
103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
113e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * See the License for the specific language governing permissions and
143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * limitations under the License.
153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */
163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpackage com.android.quicksearchbox;
183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
19c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringertimport com.android.quicksearchbox.ui.CorpusViewFactory;
20c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringertimport com.android.quicksearchbox.ui.CorpusViewInflater;
21816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport com.android.quicksearchbox.ui.DelayingSuggestionsAdapter;
22dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringertimport com.android.quicksearchbox.ui.EmptySuggestionsFooter;
23185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionViewFactory;
24185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionViewInflater;
25816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsAdapter;
26883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsFooter;
2772f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringertimport com.android.quicksearchbox.util.Factory;
28a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.NamedTaskExecutor;
29a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.PerNameExecutor;
30148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringertimport com.android.quicksearchbox.util.PriorityThreadFactory;
31a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.SingleThreadNamedTaskExecutor;
32148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringertimport com.google.common.util.concurrent.NamingThreadFactory;
33185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert
343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.Application;
353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Handler;
363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Looper;
37148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringertimport android.os.Process;
383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
3972f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringertimport java.util.concurrent.Executor;
4072f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringertimport java.util.concurrent.Executors;
413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport java.util.concurrent.ThreadFactory;
423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class QsbApplication extends Application {
443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
450484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    private Handler mUiThreadHandler;
463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    private Config mConfig;
47883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    private Corpora mCorpora;
48fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private CorpusRanker mCorpusRanker;
493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    private ShortcutRepository mShortcutRepository;
5094e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney    private ShortcutRefresher mShortcutRefresher;
51a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert    private NamedTaskExecutor mSourceTaskExecutor;
5272f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    private ThreadFactory mQueryThreadFactory;
5347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    private SuggestionsProvider mSuggestionsProvider;
54185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert    private SuggestionViewFactory mSuggestionViewFactory;
55c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    private CorpusViewFactory mCorpusViewFactory;
56ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    private Logger mLogger;
573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    @Override
593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    public void onTerminate() {
603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        close();
613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        super.onTerminate();
623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
64fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    protected void checkThread() {
65fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (Looper.myLooper() != Looper.getMainLooper()) {
66fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            throw new IllegalStateException("Accessed Application object from thread "
67fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert                    + Thread.currentThread().getName());
68fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        }
69fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
70fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
713e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    protected void close() {
72fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
73af736c70f989ebd716e0e389a28c6604b218e14fBjorn Bringert        if (mConfig != null) {
74af736c70f989ebd716e0e389a28c6604b218e14fBjorn Bringert            mConfig.close();
75af736c70f989ebd716e0e389a28c6604b218e14fBjorn Bringert            mConfig = null;
76af736c70f989ebd716e0e389a28c6604b218e14fBjorn Bringert        }
773e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        if (mShortcutRepository != null) {
783e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mShortcutRepository.close();
793e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mShortcutRepository = null;
803e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
813e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        if (mSourceTaskExecutor != null) {
823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mSourceTaskExecutor.close();
833e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mSourceTaskExecutor = null;
843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
8547d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        if (mSuggestionsProvider != null) {
8647d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert            mSuggestionsProvider.close();
8747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert            mSuggestionsProvider = null;
883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
91fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public synchronized Handler getMainThreadHandler() {
920484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        if (mUiThreadHandler == null) {
93fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            mUiThreadHandler = new Handler(Looper.getMainLooper());
940484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        }
950484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        return mUiThreadHandler;
960484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
970484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
9881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert    public void runOnUiThread(Runnable action) {
9981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert        getMainThreadHandler().post(action);
10081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert    }
10181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert
102fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
103fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the QSB configuration object.
104fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May be called from any thread.
105fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
106fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public synchronized Config getConfig() {
1073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        if (mConfig == null) {
1083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mConfig = createConfig();
1093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
1103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        return mConfig;
1113e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
1123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
1133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    protected Config createConfig() {
1143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        return new Config(this);
1153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
1163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
117fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
118fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the corpora.
119fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
120fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
121fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public Corpora getCorpora() {
122fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
123fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (mCorpora == null) {
124fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            mCorpora = createCorpora();
1253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
126fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return mCorpora;
1273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
1283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
129883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    protected Corpora createCorpora() {
130dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert        SearchableCorpora corpora = new SearchableCorpora(this, getConfig(), createSources(),
131dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert                createCorpusFactory());
13221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        corpora.update();
133fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return corpora;
1343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
1353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
13621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert    /**
13721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert     * Updates the corpora, if they are loaded.
13821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert     * May only be called from the main thread.
13921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert     */
14021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert    public void updateCorpora() {
14121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        checkThread();
14221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        if (mCorpora != null) {
14321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert            mCorpora.update();
14421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        }
14521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert    }
14621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert
147883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    protected Sources createSources() {
14821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        return new SearchableSources(this);
149883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    }
150883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert
151883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    protected CorpusFactory createCorpusFactory() {
15272f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        int numWebCorpusThreads = getConfig().getNumWebCorpusThreads();
15372f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        return new SearchableCorpusFactory(this, createExecutorFactory(numWebCorpusThreads));
15472f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    }
15572f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert
15672f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    protected Factory<Executor> createExecutorFactory(final int numThreads) {
15772f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        final ThreadFactory threadFactory = getQueryThreadFactory();
15872f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        return new Factory<Executor>() {
15972f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert            public Executor create() {
16072f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert                return Executors.newFixedThreadPool(numThreads, threadFactory);
16172f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert            }
16272f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        };
163883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    }
164883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert
165fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
166fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the corpus ranker.
167fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
168fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
169fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public CorpusRanker getCorpusRanker() {
170fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
171fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (mCorpusRanker == null) {
172fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            mCorpusRanker = createCorpusRanker();
173fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        }
174fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return mCorpusRanker;
175fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
176fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
177fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    protected CorpusRanker createCorpusRanker() {
178ce4cdcf739b57563ddcdbed6944128b8c1f7522aBjorn Bringert        return new DefaultCorpusRanker(getCorpora(), getShortcutRepository());
179fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
180fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
181fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
182fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the shortcut repository.
183fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
184fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
1853e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    public ShortcutRepository getShortcutRepository() {
186fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
1873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        if (mShortcutRepository == null) {
1883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mShortcutRepository = createShortcutRepository();
1893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
1903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        return mShortcutRepository;
1913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
1923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
193fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    protected ShortcutRepository createShortcutRepository() {
194148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert        ThreadFactory logThreadFactory = new NamingThreadFactory("ShortcutRepositoryWriter #%d",
195148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert                new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND));
196148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert        Executor logExecutor = Executors.newSingleThreadExecutor(logThreadFactory);
197fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return ShortcutRepositoryImplLog.create(this, getConfig(), getCorpora(),
198148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert            getShortcutRefresher(), getMainThreadHandler(), logExecutor);
199fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    }
200fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert
201fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
202fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the shortcut refresher.
203fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
204fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
20594e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney    public ShortcutRefresher getShortcutRefresher() {
206fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
20794e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney        if (mShortcutRefresher == null) {
20894e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney            mShortcutRefresher = createShortcutRefresher();
20994e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney        }
21094e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney        return mShortcutRefresher;
21194e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney    }
21294e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney
21394e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney    protected ShortcutRefresher createShortcutRefresher() {
21494e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney        // For now, ShortcutRefresher gets its own SourceTaskExecutor
21504a180b52fb4100a2f3747e795fb5d26e3207a4aBjorn Bringert        return new SourceShortcutRefresher(createSourceTaskExecutor());
2163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
2173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
218fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
219fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the source task executor.
220fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
221fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
222a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert    public NamedTaskExecutor getSourceTaskExecutor() {
223fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
2243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        if (mSourceTaskExecutor == null) {
2253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert            mSourceTaskExecutor = createSourceTaskExecutor();
2263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        }
2273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        return mSourceTaskExecutor;
2283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
2293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
230a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert    protected NamedTaskExecutor createSourceTaskExecutor() {
2313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        Config config = getConfig();
23272f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        ThreadFactory queryThreadFactory = getQueryThreadFactory();
233a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert        return new PerNameExecutor(SingleThreadNamedTaskExecutor.factory(queryThreadFactory));
2343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
2353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert
236fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
23772f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert     * Gets the query thread factory.
23872f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert     * May only be called from the main thread.
23972f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert     */
24072f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    protected ThreadFactory getQueryThreadFactory() {
24172f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        checkThread();
24272f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        if (mQueryThreadFactory == null) {
24372f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert            mQueryThreadFactory = createQueryThreadFactory();
24472f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        }
24572f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert        return mQueryThreadFactory;
24672f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    }
24772f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert
24872f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    protected ThreadFactory createQueryThreadFactory() {
249148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert        String nameFormat = "QSB #%d";
250148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert        int priority = getConfig().getQueryThreadPriority();
251148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert        return new NamingThreadFactory(nameFormat,
252148154b406d3e483018e98f8f0296b59302020a3Bjorn Bringert                new PriorityThreadFactory(priority));
25372f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    }
25472f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert
25572f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringert    /**
25647d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert     * Gets the suggestion provider.
257fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
258fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
25947d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    protected SuggestionsProvider getSuggestionsProvider() {
260fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
26147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        if (mSuggestionsProvider == null) {
26247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert            mSuggestionsProvider = createSuggestionsProvider();
2630484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        }
26447d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        return mSuggestionsProvider;
2650484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
2660484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
26747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    protected SuggestionsProvider createSuggestionsProvider() {
26839bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        Promoter promoter =  new ShortcutPromoter(
26939bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                new RankAwarePromoter(getConfig(), getCorpora()));
27047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        SuggestionsProvider provider = new SuggestionsProviderImpl(getConfig(),
2713e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert                getSourceTaskExecutor(),
272fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert                getMainThreadHandler(),
2733e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert                promoter,
274f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert                getShortcutRepository(),
27539bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                getCorpora(),
27681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert                getCorpusRanker(),
277f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert                getLogger());
2783e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert        return provider;
2793e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert    }
280185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert
281fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
282fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the suggestion view factory.
283fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
284fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
285185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert    public SuggestionViewFactory getSuggestionViewFactory() {
286fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
287185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert        if (mSuggestionViewFactory == null) {
288185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert            mSuggestionViewFactory = createSuggestionViewFactory();
289185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert        }
290185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert        return mSuggestionViewFactory;
291185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert    }
292185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert
293185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert    protected SuggestionViewFactory createSuggestionViewFactory() {
294185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert        return new SuggestionViewInflater(this);
295185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert    }
296185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert
297fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
298c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert     * Gets the corpus view factory.
299c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert     * May only be called from the main thread.
300c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert     */
301c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    public CorpusViewFactory getCorpusViewFactory() {
302c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        checkThread();
303c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        if (mCorpusViewFactory == null) {
304c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert            mCorpusViewFactory = createCorpusViewFactory();
305c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        }
306c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        return mCorpusViewFactory;
307c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    }
308c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert
309c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    protected CorpusViewFactory createCorpusViewFactory() {
310c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        return new CorpusViewInflater(this);
311c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    }
312c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert
313c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    /**
314fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Creates a suggestions adapter.
315fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
316fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
317816804b67619af133860a1e28e92f58bc642260dBjorn Bringert    public SuggestionsAdapter createSuggestionsAdapter() {
318816804b67619af133860a1e28e92f58bc642260dBjorn Bringert        Config config = getConfig();
319816804b67619af133860a1e28e92f58bc642260dBjorn Bringert        SuggestionViewFactory viewFactory = getSuggestionViewFactory();
320816804b67619af133860a1e28e92f58bc642260dBjorn Bringert        DelayingSuggestionsAdapter adapter = new DelayingSuggestionsAdapter(viewFactory);
321816804b67619af133860a1e28e92f58bc642260dBjorn Bringert        return adapter;
322816804b67619af133860a1e28e92f58bc642260dBjorn Bringert    }
323e72a6418e84a89d2bfd4e9d22282eca95357e0daBjorn Bringert
324dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert    /**
325dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert     * Creates a footer view to add at the bottom of the search activity.
326dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert     */
327883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    public SuggestionsFooter createSuggestionsFooter() {
328dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert        return new EmptySuggestionsFooter(this);
329883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert    }
330883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert
331fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    /**
332fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * Gets the event logger.
333fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     * May only be called from the main thread.
334fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert     */
335ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    public Logger getLogger() {
336fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        checkThread();
337ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        if (mLogger == null) {
338ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert            mLogger = createLogger();
339ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        }
340ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert        return mLogger;
341ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
342ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert
343ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    protected Logger createLogger() {
344f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        return new EventLogLogger(this, getConfig());
345ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert    }
3463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert}
347