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.os.Handler;
20 import android.util.Log;
21 
22 import com.android.quicksearchbox.util.BatchingNamedTaskExecutor;
23 import com.android.quicksearchbox.util.Consumer;
24 import com.android.quicksearchbox.util.NamedTaskExecutor;
25 import com.android.quicksearchbox.util.NoOpConsumer;
26 
27 /**
28  * Suggestions provider implementation.
29  *
30  * The provider will only handle a single query at a time. If a new query comes
31  * in, the old one is cancelled.
32  */
33 public class SuggestionsProviderImpl implements SuggestionsProvider {
34 
35     private static final boolean DBG = false;
36     private static final String TAG = "QSB.SuggestionsProviderImpl";
37 
38     private final Config mConfig;
39 
40     private final NamedTaskExecutor mQueryExecutor;
41 
42     private final Handler mPublishThread;
43 
44     private final Logger mLogger;
45 
SuggestionsProviderImpl(Config config, NamedTaskExecutor queryExecutor, Handler publishThread, Logger logger)46     public SuggestionsProviderImpl(Config config,
47             NamedTaskExecutor queryExecutor,
48             Handler publishThread,
49             Logger logger) {
50         mConfig = config;
51         mQueryExecutor = queryExecutor;
52         mPublishThread = publishThread;
53         mLogger = logger;
54     }
55 
56     @Override
close()57     public void close() {
58     }
59 
60     @Override
getSuggestions(String query, Source sourceToQuery)61     public Suggestions getSuggestions(String query, Source sourceToQuery) {
62         if (DBG) Log.d(TAG, "getSuggestions(" + query + ")");
63         final Suggestions suggestions = new Suggestions(query, sourceToQuery);
64         Log.i(TAG, "chars:" + query.length() + ",source:" + sourceToQuery);
65 
66         Consumer<SourceResult> receiver;
67         if (shouldDisplayResults(query)) {
68             receiver = new SuggestionCursorReceiver(suggestions);
69         } else {
70             receiver = new NoOpConsumer<SourceResult>();
71             suggestions.done();
72         }
73 
74         int maxResults = mConfig.getMaxResultsPerSource();
75         QueryTask.startQuery(query, maxResults, sourceToQuery, mQueryExecutor,
76                 mPublishThread, receiver);
77 
78         return suggestions;
79     }
80 
shouldDisplayResults(String query)81     private boolean shouldDisplayResults(String query) {
82         if (query.length() == 0 && !mConfig.showSuggestionsForZeroQuery()) {
83             // Note that even though we don't display such results, it's
84             // useful to run the query itself because it warms up the network
85             // connection.
86             return false;
87         }
88         return true;
89     }
90 
91 
92     private class SuggestionCursorReceiver implements Consumer<SourceResult> {
93         private final Suggestions mSuggestions;
94 
SuggestionCursorReceiver(Suggestions suggestions)95         public SuggestionCursorReceiver(Suggestions suggestions) {
96             mSuggestions = suggestions;
97         }
98 
99         @Override
consume(SourceResult cursor)100         public boolean consume(SourceResult cursor) {
101             if (DBG) {
102                 Log.d(TAG, "SuggestionCursorReceiver.consume(" + cursor + ") corpus=" +
103                         cursor.getSource() + " count = " + cursor.getCount());
104             }
105             // publish immediately
106             if (DBG) Log.d(TAG, "Publishing results");
107             mSuggestions.addResults(cursor);
108             if (cursor != null && mLogger != null) {
109                 mLogger.logLatency(cursor);
110             }
111             return true;
112         }
113 
114     }
115 }
116