1 /* 2 * Copyright (C) 2022 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 package com.android.quicksearchbox 17 18 import android.os.Handler 19 import android.util.Log 20 import com.android.quicksearchbox.util.Consumer 21 import com.android.quicksearchbox.util.NamedTaskExecutor 22 import com.android.quicksearchbox.util.NoOpConsumer 23 24 /** 25 * Suggestions provider implementation. 26 * 27 * The provider will only handle a single query at a time. If a new query comes in, the old one is 28 * cancelled. 29 */ 30 class SuggestionsProviderImpl( 31 private val mConfig: Config, 32 private val mQueryExecutor: NamedTaskExecutor, 33 publishThread: Handler?, 34 logger: Logger? 35 ) : SuggestionsProvider { 36 37 private val mPublishThread: Handler? 38 39 private val mLogger: Logger? 40 closenull41 @Override override fun close() {} 42 43 @Override getSuggestionsnull44 override fun getSuggestions(query: String, source: Source): Suggestions { 45 if (DBG) Log.d(TAG, "getSuggestions($query)") 46 val suggestions = Suggestions(query, source) 47 Log.i(TAG, "chars:" + query.length.toString() + ",source:" + source) 48 val receiver: Consumer<SourceResult?> 49 if (shouldDisplayResults(query)) { 50 receiver = SuggestionCursorReceiver(suggestions) 51 } else { 52 receiver = NoOpConsumer() 53 suggestions.done() 54 } 55 val maxResults: Int = mConfig.maxResultsPerSource 56 QueryTask.startQuery(query, maxResults, source, mQueryExecutor, mPublishThread, receiver) 57 return suggestions 58 } 59 shouldDisplayResultsnull60 private fun shouldDisplayResults(query: String): Boolean { 61 return !(query.isEmpty() && !mConfig.showSuggestionsForZeroQuery()) 62 } 63 64 private inner class SuggestionCursorReceiver(private val mSuggestions: Suggestions) : 65 Consumer<SourceResult?> { 66 @Override consumenull67 override fun consume(value: SourceResult?): Boolean { 68 if (DBG) { 69 Log.d( 70 TAG, 71 "SuggestionCursorReceiver.consume(" + 72 value + 73 ") corpus=" + 74 value?.source + 75 " count = " + 76 value?.count 77 ) 78 } 79 // publish immediately 80 if (DBG) Log.d(TAG, "Publishing results") 81 mSuggestions.addResults(value) 82 if (value != null && mLogger != null) { 83 mLogger.logLatency(value) 84 } 85 return true 86 } 87 } 88 89 companion object { 90 private const val DBG = false 91 private const val TAG = "QSB.SuggestionsProviderImpl" 92 } 93 94 init { 95 mPublishThread = publishThread 96 mLogger = logger 97 } 98 } 99