10484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert/* 20484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Copyright (C) 2009 The Android Open Source Project 30484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * 40484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 50484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * you may not use this file except in compliance with the License. 60484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * You may obtain a copy of the License at 70484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * 80484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 90484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * 100484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 110484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 120484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * See the License for the specific language governing permissions and 140484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * limitations under the License. 150484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert */ 160484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 170484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringertpackage com.android.quicksearchbox; 180484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 19ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwoodimport android.os.Handler; 20ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwoodimport android.util.Log; 21ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood 22a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.BatchingNamedTaskExecutor; 23f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringertimport com.android.quicksearchbox.util.Consumer; 24a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.NamedTaskExecutor; 25233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontayimport com.android.quicksearchbox.util.NoOpConsumer; 26a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert 270484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert/** 2847d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert * Suggestions provider implementation. 290484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * 300484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * The provider will only handle a single query at a time. If a new query comes 3154af8b26e73f9aa2a01473517cf6d9980a95fe55Mathew Inwood * in, the old one is cancelled. 320484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert */ 33b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertpublic class SuggestionsProviderImpl implements SuggestionsProvider { 340484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 35b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert private static final boolean DBG = false; 3647d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert private static final String TAG = "QSB.SuggestionsProviderImpl"; 370484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 380484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private final Config mConfig; 390484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 40a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert private final NamedTaskExecutor mQueryExecutor; 410484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 420484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private final Handler mPublishThread; 430484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 4481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert private final Logger mLogger; 4581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 46b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert public SuggestionsProviderImpl(Config config, 47a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert NamedTaskExecutor queryExecutor, 480484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert Handler publishThread, 49f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert Logger logger) { 500484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert mConfig = config; 510484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert mQueryExecutor = queryExecutor; 520484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert mPublishThread = publishThread; 5381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert mLogger = logger; 540484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 550484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 56ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood @Override 570484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert public void close() { 580484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 590484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 60ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood @Override 61ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood public Suggestions getSuggestions(String query, Source sourceToQuery) { 620484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert if (DBG) Log.d(TAG, "getSuggestions(" + query + ")"); 63ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood final Suggestions suggestions = new Suggestions(query, sourceToQuery); 64ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood Log.i(TAG, "chars:" + query.length() + ",source:" + sourceToQuery); 6539bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney 66ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood Consumer<SourceResult> receiver; 67233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay if (shouldDisplayResults(query)) { 68ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood receiver = new SuggestionCursorReceiver(suggestions); 69233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay } else { 70ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood receiver = new NoOpConsumer<SourceResult>(); 713540e5a9eab6ff33e6d45f1d908bcaf4c4f49152Bjorn Bringert suggestions.done(); 72233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay } 730484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 74ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood int maxResults = mConfig.getMaxResultsPerSource(); 75ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood QueryTask.startQuery(query, maxResults, sourceToQuery, mQueryExecutor, 76ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood mPublishThread, receiver); 770484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 780484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert return suggestions; 790484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 800484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 81233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay private boolean shouldDisplayResults(String query) { 82233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay if (query.length() == 0 && !mConfig.showSuggestionsForZeroQuery()) { 83233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay // Note that even though we don't display such results, it's 84233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay // useful to run the query itself because it warms up the network 85233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay // connection. 86233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay return false; 87233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay } 88233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay return true; 89233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay } 90233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay 91233f899a01d805b27f17ce4f72fdbc7c279c6c36Peter Visontay 92ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood private class SuggestionCursorReceiver implements Consumer<SourceResult> { 93b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private final Suggestions mSuggestions; 9439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney 95ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood public SuggestionCursorReceiver(Suggestions suggestions) { 9627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney mSuggestions = suggestions; 9727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 9827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 99ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood @Override 100ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood public boolean consume(SourceResult cursor) { 101848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (DBG) { 102848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani Log.d(TAG, "SuggestionCursorReceiver.consume(" + cursor + ") corpus=" + 103ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood cursor.getSource() + " count = " + cursor.getCount()); 104f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert } 105ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood // publish immediately 106ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood if (DBG) Log.d(TAG, "Publishing results"); 107ecf356c15143ab0583c64682de16d94a57f7dd1cMathew Inwood mSuggestions.addResults(cursor); 108f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (cursor != null && mLogger != null) { 109f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mLogger.logLatency(cursor); 110f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 111f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert return true; 11227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney } 11327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney 1140484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 1150484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert} 116