SearchActivity.java revision 7a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24
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 193f71a11f8858b9164ca83e8d2f558dd8a8a5e2deBjorn Bringertimport com.android.common.Search; 207010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringertimport com.android.quicksearchbox.ui.SearchActivityView; 21185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionClickListener; 22185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsAdapter; 23b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringertimport com.android.quicksearchbox.util.Consumer; 24b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringertimport com.android.quicksearchbox.util.Consumers; 252607687d72deb8e06329597ab8bffcca9c746153Mathew Inwoodimport com.google.common.annotations.VisibleForTesting; 263a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringertimport com.google.common.base.CharMatcher; 27185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.Activity; 293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.SearchManager; 30dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringertimport android.content.DialogInterface; 313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.content.Intent; 3221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringertimport android.database.DataSetObserver; 33fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.net.Uri; 343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Bundle; 3511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport android.os.Debug; 364ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringertimport android.os.Handler; 373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextUtils; 383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.util.Log; 393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.Menu; 403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View; 41fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringertimport android.widget.Toast; 423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport java.io.File; 44dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringertimport java.util.ArrayList; 454572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwoodimport java.util.Collection; 46b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertimport java.util.List; 475f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringertimport java.util.Set; 48ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/** 503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * The main activity for Quick Search Box. Shows the search UI. 513e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class SearchActivity extends Activity { 543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 55754cb6b769c5955fc707a6c5ab6689b64df102b3Mathew Inwood private static final boolean DBG = false; 560484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private static final String TAG = "QSB.SearchActivity"; 5711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private static final boolean TRACE = false; 583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 59fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String SCHEME_CORPUS = "qsb.corpus"; 60fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 61fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static final String INTENT_ACTION_QSB_AND_SELECT_CORPUS 62fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert = "com.android.quicksearchbox.action.QSB_AND_SELECT_CORPUS"; 633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 649ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Keys for the saved instance state. 65fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String INSTANCE_KEY_CORPUS = "corpus"; 66839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert private static final String INSTANCE_KEY_QUERY = "query"; 67713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 68f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // Measures time from for last onCreate()/onNewIntent() call. 69f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private LatencyTracker mStartLatencyTracker; 7098cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood // Measures time spent inside onCreate() 7198cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private LatencyTracker mOnCreateTracker; 7298cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private int mOnCreateLatency; 73ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // Whether QSB is starting. True between the calls to onCreate()/onNewIntent() and onResume(). 74ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mStarting; 75ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // True if the user has taken some action, e.g. launching a search, voice search, 76ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // or suggestions, since QSB was last started. 77ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mTookAction; 78ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 797010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert private SearchActivityView mSearchActivityView; 80185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 8121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private CorporaObserver mCorporaObserver; 8221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 832617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert private Bundle mAppSearchData; 843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 85d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Handler mHandler = new Handler(); 86d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mUpdateSuggestionsTask = new Runnable() { 874ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert public void run() { 887f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert updateSuggestions(); 894ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 904ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert }; 914ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 92d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mShowInputMethodTask = new Runnable() { 93d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void run() { 947010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.showInputMethodForQuery(); 95d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 96d98911178013162737fbba74387b51d2a08b0493Amith Yamasani }; 97d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 982607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood private OnDestroyListener mDestroyListener; 992607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 1003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** Called when the activity is first created. */ 1013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 1023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onCreate(Bundle savedInstanceState) { 10311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) startMethodTracing(); 104ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onCreate()"); 1063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreate(savedInstanceState); 107713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1085880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert mSearchActivityView = setupContentView(); 109aa7d79792baca59eb7afe00ea27abc5176ddd34bMathew Inwood 110fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood if (getConfig().showScrollingSuggestions()) { 111f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood mSearchActivityView.setMaxPromotedSuggestions(getConfig().getMaxPromotedSuggestions()); 112fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood } else { 113fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood mSearchActivityView.limitSuggestionsToViewHeight(); 114fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood } 115f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood if (getConfig().showScrollingResults()) { 1167a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mSearchActivityView.setMaxPromotedResults(getConfig().getMaxPromotedResults()); 117f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood } else { 118f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood mSearchActivityView.limitResultsToViewHeight(); 119f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood } 120848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 1217010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSearchClickListener(new SearchActivityView.SearchClickListener() { 1227010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public boolean onSearchClicked(int method) { 1237010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return SearchActivity.this.onSearchClicked(method); 1247010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1257010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 1262617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 1277010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setQueryListener(new SearchActivityView.QueryListener() { 1287010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public void onQueryChanged() { 1297010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert updateSuggestionsBuffered(); 1307010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1317010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 132782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 1337010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSuggestionClickListener(new ClickHandler()); 1347be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 1357010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSettingsButtonClickListener(new View.OnClickListener() { 1367010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public void onClick(View v) { 1377010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert onSettingsClicked(); 1387010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1397010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 140848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 1417010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setVoiceSearchButtonClickListener(new View.OnClickListener() { 1427010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public void onClick(View view) { 1437010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert onVoiceSearchClicked(); 1447010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1457010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 1469ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 147e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood View.OnClickListener finishOnClick = new View.OnClickListener() { 1489e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood public void onClick(View v) { 1499e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood finish(); 1509e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood } 151e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood }; 152e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood mSearchActivityView.setExitClickListener(finishOnClick); 153e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood mSearchActivityView.setEmptySpaceClickListener(finishOnClick); 1549e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood 1559ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // First get setup from intent 1569ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Intent intent = getIntent(); 1579ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1589ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Then restore any saved instance state 1599ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert restoreInstanceState(savedInstanceState); 1609ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 161713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // Do this at the end, to avoid updating the list view when setSource() 162713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // is called. 1637010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.start(); 16421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 16521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorporaObserver = new CorporaObserver(); 16621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().registerDataSetObserver(mCorporaObserver); 16798cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood recordOnCreateDone(); 1689ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 169713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1705880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected SearchActivityView setupContentView() { 1716ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert setContentView(R.layout.search_activity); 1725880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert return (SearchActivityView) findViewById(R.id.search_activity_view); 1735880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert } 1745880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert 1755880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected SearchActivityView getSearchActivityView() { 1765880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert return mSearchActivityView; 1776ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert } 1786ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert 17911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private void startMethodTracing() { 18011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert File traceDir = getDir("traces", 0); 18111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String traceFile = new File(traceDir, "qsb.trace").getAbsolutePath(); 18211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert Debug.startMethodTracing(traceFile); 18311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 18411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 1859ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert @Override 1869ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onNewIntent(Intent intent) { 187839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onNewIntent()"); 188ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1899ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setIntent(intent); 1909ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1919ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 1929ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 193ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private void recordStartTime() { 194f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mStartLatencyTracker = new LatencyTracker(); 19598cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood mOnCreateTracker = new LatencyTracker(); 196ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mStarting = true; 197ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = false; 198ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 199ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 20098cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private void recordOnCreateDone() { 20198cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood mOnCreateLatency = mOnCreateTracker.getLatency(); 20298cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood } 20398cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood 2049ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void restoreInstanceState(Bundle savedInstanceState) { 2059ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (savedInstanceState == null) return; 206fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = savedInstanceState.getString(INSTANCE_KEY_CORPUS); 207839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert String query = savedInstanceState.getString(INSTANCE_KEY_QUERY); 20821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 209839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, false); 210713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 211713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 212713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert @Override 2139ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onSaveInstanceState(Bundle outState) { 2149ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert super.onSaveInstanceState(outState); 2159ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // We don't save appSearchData, since we always get the value 2169ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // from the intent and the user can't change it. 217fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 21821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert outState.putString(INSTANCE_KEY_CORPUS, getCorpusName()); 219839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert outState.putString(INSTANCE_KEY_QUERY, getQuery()); 220713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 221713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 222713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private void setupFromIntent(Intent intent) { 223713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert if (DBG) Log.d(TAG, "setupFromIntent(" + intent.toUri(0) + ")"); 22421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert String corpusName = getCorpusNameFromUri(intent.getData()); 2252617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert String query = intent.getStringExtra(SearchManager.QUERY); 2262617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA); 227839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert boolean selectAll = intent.getBooleanExtra(SearchManager.EXTRA_SELECT_QUERY, false); 2282617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 22921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 230839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, selectAll); 231c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mAppSearchData = appSearchData; 2322617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23311c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert if (startedIntoCorpusSelectionDialog()) { 2340a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.showCorpusSelectionDialog(); 2352617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 2369ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 2379ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 23811c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert public boolean startedIntoCorpusSelectionDialog() { 23911c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert return INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(getIntent().getAction()); 24011c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert } 24111c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert 242dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert /** 243dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * Removes corpus selector intent action, so that BACK works normally after 244dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * dismissing and reopening the corpus selector. 245dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert */ 2460a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood public void clearStartedIntoCorpusSelectionDialog() { 247dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent oldIntent = getIntent(); 248dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (SearchActivity.INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(oldIntent.getAction())) { 249dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent newIntent = new Intent(oldIntent); 250dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert newIntent.setAction(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 251dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert setIntent(newIntent); 252dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 253dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 254dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 255fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static Uri getCorpusUri(Corpus corpus) { 256fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) return null; 257fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return new Uri.Builder() 258fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .scheme(SCHEME_CORPUS) 259fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .authority(corpus.getName()) 260fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .build(); 261fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 262fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 26321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusNameFromUri(Uri uri) { 264fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (uri == null) return null; 265fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (!SCHEME_CORPUS.equals(uri.getScheme())) return null; 26621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return uri.getAuthority(); 267fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 268fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 2690a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private Corpus getCorpus() { 2700a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return mSearchActivityView.getCorpus(); 271713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 272713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 2730a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private String getCorpusName() { 2740a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return mSearchActivityView.getCorpusName(); 275f165f2d6c6f8173b94937ae3202f0b638348dffdBjorn Bringert } 276f165f2d6c6f8173b94937ae3202f0b638348dffdBjorn Bringert 2770a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private void setCorpus(String name) { 2780a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.setCorpus(name); 27921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 28021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 2813e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private QsbApplication getQsbApplication() { 28249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return QsbApplication.get(this); 2833e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 2843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2854ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private Config getConfig() { 2864ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert return getQsbApplication().getConfig(); 2874ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 2884ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 28996fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert protected SearchSettings getSettings() { 29096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return getQsbApplication().getSettings(); 29196fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert } 29296fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 293b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private Corpora getCorpora() { 294b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getCorpora(); 295fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 296fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 297b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private CorpusRanker getCorpusRanker() { 298b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getCorpusRanker(); 2993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 301b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private ShortcutRepository getShortcutRepository() { 302b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getShortcutRepository(); 303848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 304848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 305b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private SuggestionsProvider getSuggestionsProvider() { 306b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getSuggestionsProvider(); 30747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 30847d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 309ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private Logger getLogger() { 310ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert return getQsbApplication().getLogger(); 311ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 312ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 3132607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood @VisibleForTesting 3142607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood public void setOnDestroyListener(OnDestroyListener l) { 3152607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood mDestroyListener = l; 3162607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 3172607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 3183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onDestroy() { 3203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onDestroy()"); 32121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().unregisterDataSetObserver(mCorporaObserver); 3227010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.destroy(); 3232607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood super.onDestroy(); 3242607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood if (mDestroyListener != null) { 3252607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood mDestroyListener.onDestroyed(); 3262607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 3273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onStop() { 3319ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onStop()"); 332f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (!mTookAction) { 333848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani // TODO: This gets logged when starting other activities, e.g. by opening the search 334f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // settings, or clicking a notification in the status bar. 335aa7d79792baca59eb7afe00ea27abc5176ddd34bMathew Inwood // TODO we should log both sets of suggestions in 2-pane mode 336f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert getLogger().logExit(getCurrentSuggestions(), getQuery().length()); 337f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 3389ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Close all open suggestion cursors. The query will be redone in onResume() 3393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // if we come back to this activity. 3407010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.clearSuggestions(); 34194e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney getQsbApplication().getShortcutRefresher().reset(); 3420a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.onStop(); 3433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onStop(); 3443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 347839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert protected void onRestart() { 348839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onRestart()"); 349839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert super.onRestart(); 350839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert } 351839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert 352839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert @Override 353b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert protected void onResume() { 3549ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onResume()"); 355b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert super.onResume(); 35611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert updateSuggestionsBuffered(); 3570a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.onResume(); 35811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) Debug.stopMethodTracing(); 359b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert } 360b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert 361b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert @Override 3623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onCreateOptionsMenu(Menu menu) { 3633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreateOptionsMenu(menu); 36496fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert getSettings().addMenuItems(menu); 36596fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return true; 36696fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert } 36796fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 36896fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert @Override 36996fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert public boolean onPrepareOptionsMenu(Menu menu) { 37096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert super.onPrepareOptionsMenu(menu); 37196fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert getSettings().updateMenuItems(menu); 3723e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 3733e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3743e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 375d98911178013162737fbba74387b51d2a08b0493Amith Yamasani @Override 376d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void onWindowFocusChanged(boolean hasFocus) { 377d98911178013162737fbba74387b51d2a08b0493Amith Yamasani super.onWindowFocusChanged(hasFocus); 378d98911178013162737fbba74387b51d2a08b0493Amith Yamasani if (hasFocus) { 379d98911178013162737fbba74387b51d2a08b0493Amith Yamasani // Launch the IME after a bit 380d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mShowInputMethodTask, 0); 381d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 382d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 383d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 384713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert protected String getQuery() { 3857010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return mSearchActivityView.getQuery(); 3863e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3887010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert protected void setQuery(String query, boolean selectAll) { 3897010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setQuery(query, selectAll); 390e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 391e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 3920a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood public CorpusSelectionDialog getCorpusSelectionDialog() { 3930a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood CorpusSelectionDialog dialog = createCorpusSelectionDialog(); 3940a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood dialog.setOwnerActivity(this); 3950a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood dialog.setOnDismissListener(new CorpusSelectorDismissListener()); 3960a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return dialog; 3972617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 3982617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 39923db3f9877e691568fe2c955fd9d4f48a2eb937aMathew Inwood protected CorpusSelectionDialog createCorpusSelectionDialog() { 40096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return new CorpusSelectionDialog(this, getSettings()); 40135c43805a450c17d5fc5e27dc073edc6e2cd7320Amith Yamasani } 40235c43805a450c17d5fc5e27dc073edc6e2cd7320Amith Yamasani 403dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood /** 404dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood * @return true if a search was performed as a result of this click, false otherwise. 405dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood */ 406dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood protected boolean onSearchClicked(int method) { 4073a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringert String query = CharMatcher.WHITESPACE.trimAndCollapseFrom(getQuery(), ' '); 4083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Search clicked, query=" + query); 409eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 410eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert // Don't do empty queries 411dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (TextUtils.getTrimmedLength(query) == 0) return false; 412eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 41381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 414dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (searchCorpus == null) return false; 415c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 416ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 417c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 418c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log search start 4190a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood getLogger().logSearch(getCorpus(), method, query.length()); 420c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 421c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 422c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert SuggestionData searchShortcut = searchCorpus.createSearchShortcut(query); 423c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchShortcut != null) { 42493bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert ListSuggestionCursor cursor = new ListSuggestionCursor(query); 425c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert cursor.add(searchShortcut); 426c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getShortcutRepository().reportClick(cursor, 0); 427c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 428c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 429c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start search 4309d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert startSearch(searchCorpus, query); 4319d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert return true; 4329d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert } 4339d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 4349d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert protected void startSearch(Corpus searchCorpus, String query) { 435c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createSearchIntent(query, mAppSearchData); 43681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 4373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onVoiceSearchClicked() { 4403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Voice Search clicked"); 44181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 442c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 443c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 444535931433926d342c6277034cad91143ae28b72dBjorn Bringert mTookAction = true; 445535931433926d342c6277034cad91143ae28b72dBjorn Bringert 446c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log voice search start 447c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getLogger().logVoiceSearch(searchCorpus); 448ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 449c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start voice search 450c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createVoiceSearchIntent(mAppSearchData); 45181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 45281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 45381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 454848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani protected void onSettingsClicked() { 45596fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert startActivity(getSettings().getSearchSettingsIntent()); 456848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 457848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 458ca9c7b7bc0183aa1b6d160bf76597c96e70831f6Mathew Inwood protected Corpus getSearchCorpus() { 4597010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return mSearchActivityView.getSearchCorpus(); 460014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 461014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 462e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert protected SuggestionCursor getCurrentSuggestions() { 463fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood return mSearchActivityView.getCurrentPromotedSuggestions(); 464782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 465782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 4667a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected SuggestionPosition getCurrentSuggestions(SuggestionsAdapter<?> adapter, long id) { 4677a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition pos = adapter.getSuggestion(id); 4687a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (pos == null) { 4697a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return null; 4707a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood } 4717a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionCursor suggestions = pos.getCursor(); 4727a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood int position = pos.getPosition(); 4735f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (suggestions == null) { 4745f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 4755f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4765f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert int count = suggestions.getCount(); 4775f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (position < 0 || position >= count) { 4785f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert Log.w(TAG, "Invalid suggestion position " + position + ", count = " + count); 4795f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 4805f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4815f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert suggestions.moveTo(position); 4827a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return pos; 4835f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4845f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 4855f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert protected Set<Corpus> getCurrentIncludedCorpora() { 4867010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert Suggestions suggestions = mSearchActivityView.getSuggestions(); 487848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani return suggestions == null ? null : suggestions.getIncludedCorpora(); 4885f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4895f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 49081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert protected void launchIntent(Intent intent) { 49113b4f2dc4b339790c2b9b0220be47c8e77fd61eaMathew Inwood if (DBG) Log.d(TAG, "launchIntent " + intent); 49281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (intent == null) { 49381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return; 49481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 49581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert try { 49681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert startActivity(intent); 49781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } catch (RuntimeException ex) { 49881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // Since the intents for suggestions specified by suggestion providers, 49981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // guard against them not being handled, not allowed, etc. 50081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "Failed to start " + intent.toUri(0), ex); 50181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 50281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 50381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 5047a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood private boolean launchSuggestion(SuggestionsAdapter<?> adapter, long id) { 5057a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5067a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return false; 5076f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert 5087a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "Launching suggestion " + id); 509ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 510e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert 511c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log suggestion click 5127a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 513c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_LAUNCH); 514ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 515c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 5167a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getShortcutRepository().reportClick(suggestion.getCursor(), suggestion.getPosition()); 517c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 518c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Launch intent 5197a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood launchSuggestion(suggestion.getCursor(), suggestion.getPosition()); 5209d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 5219d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert return true; 5229d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert } 5239d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 5249d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert protected void launchSuggestion(SuggestionCursor suggestions, int position) { 52581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert suggestions.moveTo(position); 52693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert Intent intent = SuggestionUtils.getSuggestionIntent(suggestions, mAppSearchData); 52781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 5283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5307a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void removeFromHistory(SuggestionsAdapter<?> adapter, long id) { 5317a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5327a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return; 5337a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood removeFromHistory(suggestion.getCursor(), suggestion.getPosition()); 534fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert // TODO: Log to event log? 535fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 536fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 537fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeFromHistory(SuggestionCursor suggestions, int position) { 538fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert removeShortcut(suggestions, position); 539fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert removeFromHistoryDone(true); 540fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 541fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 542fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeFromHistoryDone(boolean ok) { 543fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert Log.i(TAG, "Removed query from history, success=" + ok); 544fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert updateSuggestionsBuffered(); 545fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (!ok) { 546fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert Toast.makeText(this, R.string.remove_from_history_failed, Toast.LENGTH_SHORT).show(); 547fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 548fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 549fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 550fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeShortcut(SuggestionCursor suggestions, int position) { 551fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (suggestions.isSuggestionShortcut()) { 552fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (DBG) Log.d(TAG, "Removing suggestion " + position + " from shortcuts"); 553fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert getShortcutRepository().removeFromHistory(suggestions, position); 554fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 555fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 556fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 5577a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void clickedQuickContact(SuggestionsAdapter<?> adapter, long id) { 5587a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5597a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return; 560c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 5617a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "Used suggestion " + suggestion.getPosition()); 562c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert mTookAction = true; 563c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 564c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert // Log suggestion click 5657a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 566c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_QUICK_CONTACT); 567c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 568c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert // Create shortcut 5697a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getShortcutRepository().reportClick(suggestion.getCursor(), suggestion.getPosition()); 570c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert } 571c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 5727a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void refineSuggestion(SuggestionsAdapter<?> adapter, long id) { 5737a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "query refine clicked, pos " + id); 5747a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5757a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) { 5765f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 5775f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5787a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood String query = suggestion.getSuggestionQuery(); 5795f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (TextUtils.isEmpty(query)) { 5805f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 5815f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5825f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 5835f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Log refine click 5847a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 585c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_REFINE); 5865f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 5875f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Put query + space in query text view 5885f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert String queryWithSpace = query + ' '; 5895f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert setQuery(queryWithSpace, false); 590dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert updateSuggestions(); 5917010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.focusQueryTextView(); 5923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5944ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private void updateSuggestionsBuffered() { 5957f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestionsBuffered()"); 596d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.removeCallbacks(mUpdateSuggestionsTask); 5974ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert long delay = getConfig().getTypingUpdateSuggestionsDelayMillis(); 598d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mUpdateSuggestionsTask, delay); 5994ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 6004ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 601b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private void gotSuggestions(Suggestions suggestions) { 60211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (mStarting) { 60311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert mStarting = false; 60411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String source = getIntent().getStringExtra(Search.SOURCE); 60511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert int latency = mStartLatencyTracker.getLatency(); 60698cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood getLogger().logStart(mOnCreateLatency, latency, source, getCorpus(), 607848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani suggestions == null ? null : suggestions.getExpectedCorpora()); 608b5560dbe16a8fb3148b0fb24c73836bf2e84dd61Mathew Inwood getQsbApplication().onStartupComplete(); 60911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 610848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 611848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 6126859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert private void getCorporaToQuery(Consumer<List<Corpus>> consumer) { 613dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert Corpus corpus = getCorpus(); 614dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert if (corpus == null) { 615dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert getCorpusRanker().getCorporaInAll(Consumers.createAsyncConsumer(mHandler, consumer)); 616dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert } else { 617dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert List<Corpus> corpora = new ArrayList<Corpus>(); 618dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 619dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert if (searchCorpus != null) corpora.add(searchCorpus); 620dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert consumer.consume(corpora); 621dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert } 6224572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood } 6234572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood 624b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert protected void getShortcutsForQuery(String query, Collection<Corpus> corporaToQuery, 625b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert final Suggestions suggestions) { 626b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert ShortcutRepository shortcutRepo = getShortcutRepository(); 627b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert if (shortcutRepo == null) return; 628e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood if (query.length() == 0 && !getConfig().showShortcutsForZeroQuery()) { 629e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood return; 630e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood } 631b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert Consumer<ShortcutCursor> consumer = Consumers.createAsyncCloseableConsumer(mHandler, 632b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert new Consumer<ShortcutCursor>() { 633b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert public boolean consume(ShortcutCursor shortcuts) { 634b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert suggestions.setShortcuts(shortcuts); 635b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert return true; 636b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert } 637b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert }); 6388749e77dddec9e7984ee86a7be6f5ba4fce44362Bjorn Bringert shortcutRepo.getShortcutsForQuery(query, corporaToQuery, 6398749e77dddec9e7984ee86a7be6f5ba4fce44362Bjorn Bringert getSettings().allowWebSearchShortcuts(), consumer); 640b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert } 64111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 642dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert public void updateSuggestions() { 6437f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestions()"); 6447f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert final String query = CharMatcher.WHITESPACE.trimLeadingFrom(getQuery()); 6454572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood getQsbApplication().getSourceTaskExecutor().cancelPendingTasks(); 6466859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert getCorporaToQuery(new Consumer<List<Corpus>>(){ 6476859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert @Override 6486859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert public boolean consume(List<Corpus> corporaToQuery) { 6496859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert updateSuggestions(query, corporaToQuery); 6506859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert return true; 6516859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert } 6526859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert }); 6536859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert } 654b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert 6556859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert protected void updateSuggestions(String query, List<Corpus> corporaToQuery) { 6567f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestions(\"" + query+"\"," + corporaToQuery + ")"); 657b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert Suggestions suggestions = getSuggestionsProvider().getSuggestions( 658b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert query, corporaToQuery); 659b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert getShortcutsForQuery(query, corporaToQuery, suggestions); 660b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert 661b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert // Log start latency if this is the first suggestions update 662b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert gotSuggestions(suggestions); 663b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert 6645880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert showSuggestions(suggestions); 6655880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert } 6665880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert 6675880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected void showSuggestions(Suggestions suggestions) { 6687010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSuggestions(suggestions); 669185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 670185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 671185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert private class ClickHandler implements SuggestionClickListener { 672848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 6737a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQuickContactClicked(SuggestionsAdapter<?> adapter, long id) { 6747a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood clickedQuickContact(adapter, id); 675848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 6763e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6777a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionClicked(SuggestionsAdapter<?> adapter, long id) { 6787a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood launchSuggestion(adapter, id); 679848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 680145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 6817a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionRemoveFromHistoryClicked(SuggestionsAdapter<?> adapter, long id) { 6827a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood removeFromHistory(adapter, id); 683848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 6843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6857a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQueryRefineClicked(SuggestionsAdapter<?> adapter, long id) { 6867a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood refineSuggestion(adapter, id); 6872617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 688f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 689f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 690dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private class CorpusSelectorDismissListener implements DialogInterface.OnDismissListener { 691dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert public void onDismiss(DialogInterface dialog) { 692dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (DBG) Log.d(TAG, "Corpus selector dismissed"); 693dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert clearStartedIntoCorpusSelectionDialog(); 694dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 695dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 696dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 69721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private class CorporaObserver extends DataSetObserver { 69821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert @Override 69921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onChanged() { 70021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(getCorpusName()); 701dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert updateSuggestions(); 70221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 70321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 70421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 7052607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood public interface OnDestroyListener { 7062607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood void onDestroyed(); 7072607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 7082607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 7093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert} 710