SearchActivity.java revision b5560dbe16a8fb3148b0fb24c73836bf2e84dd61
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; 20c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringertimport com.android.quicksearchbox.ui.CorpusViewFactory; 21014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringertimport com.android.quicksearchbox.ui.QueryTextView; 22185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionClickListener; 23185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsAdapter; 24185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsView; 253a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringertimport com.google.common.base.CharMatcher; 26185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.Activity; 283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.SearchManager; 29dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringertimport android.content.DialogInterface; 303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.content.Intent; 3121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringertimport android.database.DataSetObserver; 32d7a95801d20a9405b4ab9c9b4beecd106e880166Bryan Mawhinneyimport android.graphics.drawable.Drawable; 33fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.net.Uri; 343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Bundle; 3511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport android.os.Debug; 364ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringertimport android.os.Handler; 373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.Editable; 383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextUtils; 393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextWatcher; 403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.util.Log; 413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.KeyEvent; 423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.Menu; 433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View; 443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View.OnFocusChangeListener; 45014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringertimport android.view.inputmethod.CompletionInfo; 463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.inputmethod.InputMethodManager; 47145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringertimport android.widget.AbsListView; 483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.widget.ImageButton; 493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport java.io.File; 51014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringertimport java.util.ArrayList; 52014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringertimport java.util.Arrays; 53e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringertimport java.util.Collection; 545f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringertimport java.util.Set; 55ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/** 573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * The main activity for Quick Search Box. Shows the search UI. 583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class SearchActivity extends Activity { 613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 62754cb6b769c5955fc707a6c5ab6689b64df102b3Mathew Inwood private static final boolean DBG = false; 630484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private static final String TAG = "QSB.SearchActivity"; 6411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private static final boolean TRACE = false; 653e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 66fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String SCHEME_CORPUS = "qsb.corpus"; 67fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 68fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static final String INTENT_ACTION_QSB_AND_SELECT_CORPUS 69fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert = "com.android.quicksearchbox.action.QSB_AND_SELECT_CORPUS"; 703e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 71e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood public static final String INTENT_ACTION_QSB_AND_HIDE_WIDGET_HINTS 72e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood = "com.android.quicksearchbox.action.QSB_AND_HIDE_WIDGET_HINTS"; 73e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood 74c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // The string used for privateImeOptions to identify to the IME that it should not show 75c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // a microphone button since one already exists in the search dialog. 76c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // TODO: This should move to android-common or something. 77c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert private static final String IME_OPTION_NO_MICROPHONE = "nm"; 78c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert 799ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Keys for the saved instance state. 80fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String INSTANCE_KEY_CORPUS = "corpus"; 81839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert private static final String INSTANCE_KEY_QUERY = "query"; 82713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 83f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // Measures time from for last onCreate()/onNewIntent() call. 84f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private LatencyTracker mStartLatencyTracker; 85ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // Whether QSB is starting. True between the calls to onCreate()/onNewIntent() and onResume(). 86ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mStarting; 87ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // True if the user has taken some action, e.g. launching a search, voice search, 88ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // or suggestions, since QSB was last started. 89ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mTookAction; 90ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 91f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private CorpusSelectionDialog mCorpusSelectionDialog; 92f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 93185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert protected SuggestionsAdapter mSuggestionsAdapter; 94185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 9521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private CorporaObserver mCorporaObserver; 9621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 97014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert protected QueryTextView mQueryTextView; 98e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert // True if the query was empty on the previous call to updateQuery() 99e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert protected boolean mQueryWasEmpty = true; 1003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected SuggestionsView mSuggestionsView; 1023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mSearchGoButton; 1043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mVoiceSearchButton; 105a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert protected ImageButton mCorpusIndicator; 1063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 107fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus mCorpus; 1082617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert private Bundle mAppSearchData; 109713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private boolean mUpdateSuggestions; 1103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 111d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Handler mHandler = new Handler(); 112d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mUpdateSuggestionsTask = new Runnable() { 1134ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert public void run() { 1144ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestions(getQuery()); 1154ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 1164ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert }; 1174ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 118d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mShowInputMethodTask = new Runnable() { 119d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void run() { 120d98911178013162737fbba74387b51d2a08b0493Amith Yamasani showInputMethodForQuery(); 121d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 122d98911178013162737fbba74387b51d2a08b0493Amith Yamasani }; 123d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 1243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** Called when the activity is first created. */ 1253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 1263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onCreate(Bundle savedInstanceState) { 12711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) startMethodTracing(); 128ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onCreate()"); 1303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreate(savedInstanceState); 131713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1326ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert setContentView(); 13366ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood SuggestListFocusListener suggestionFocusListener = new SuggestListFocusListener(); 134816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mSuggestionsAdapter = getQsbApplication().createSuggestionsAdapter(); 13566ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood mSuggestionsAdapter.setSuggestionClickListener(new ClickHandler()); 13666ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood mSuggestionsAdapter.setOnFocusChangeListener(suggestionFocusListener); 137185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 138014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mQueryTextView = (QueryTextView) findViewById(R.id.search_src_text); 1393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSuggestionsView = (SuggestionsView) findViewById(R.id.suggestions); 140145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert mSuggestionsView.setOnScrollListener(new InputMethodCloser()); 141713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setOnKeyListener(new SuggestionsViewKeyListener()); 14266ee1cc883f77fee930587503ecdcd8d18f12b23Mathew Inwood mSuggestionsView.setOnFocusChangeListener(suggestionFocusListener); 1433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSearchGoButton = (ImageButton) findViewById(R.id.search_go_btn); 1453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mVoiceSearchButton = (ImageButton) findViewById(R.id.search_voice_btn); 146a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator = (ImageButton) findViewById(R.id.corpus_indicator); 1473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 148782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.addTextChangedListener(new SearchTextWatcher()); 149782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.setOnKeyListener(new QueryTextViewKeyListener()); 1507b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.setOnFocusChangeListener(new QueryTextViewFocusListener()); 151014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mQueryTextView.setSuggestionClickListener(new ClickHandler()); 152782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 153fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnClickListener(new CorpusIndicatorClickListener()); 1542617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 155782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mSearchGoButton.setOnClickListener(new SearchGoButtonClickListener()); 156782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 157782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mVoiceSearchButton.setOnClickListener(new VoiceSearchButtonClickListener()); 1587be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 1597be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert ButtonsKeyListener buttonsKeyListener = new ButtonsKeyListener(); 1607be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mSearchGoButton.setOnKeyListener(buttonsKeyListener); 1617be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mVoiceSearchButton.setOnKeyListener(buttonsKeyListener); 162fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnKeyListener(buttonsKeyListener); 163713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1649ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mUpdateSuggestions = true; 1659ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 1669ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // First get setup from intent 1679ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Intent intent = getIntent(); 1689ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1699ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Then restore any saved instance state 1709ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert restoreInstanceState(savedInstanceState); 1719ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 172014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mSuggestionsAdapter.registerDataSetObserver(new SuggestionsObserver()); 173014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 174713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // Do this at the end, to avoid updating the list view when setSource() 175713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // is called. 176713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setAdapter(mSuggestionsAdapter); 17721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 17821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorporaObserver = new CorporaObserver(); 17921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().registerDataSetObserver(mCorporaObserver); 1809ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 181713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1826ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert protected void setContentView() { 1836ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert setContentView(R.layout.search_activity); 1846ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert } 1856ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert 18611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private void startMethodTracing() { 18711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert File traceDir = getDir("traces", 0); 18811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String traceFile = new File(traceDir, "qsb.trace").getAbsolutePath(); 18911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert Debug.startMethodTracing(traceFile); 19011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 19111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 1929ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert @Override 1939ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onNewIntent(Intent intent) { 194839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onNewIntent()"); 195ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1969ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setIntent(intent); 1979ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1989ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 1999ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 200ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private void recordStartTime() { 201f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mStartLatencyTracker = new LatencyTracker(); 202ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mStarting = true; 203ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = false; 204ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 205ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 2069ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void restoreInstanceState(Bundle savedInstanceState) { 2079ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (savedInstanceState == null) return; 208fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = savedInstanceState.getString(INSTANCE_KEY_CORPUS); 209839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert String query = savedInstanceState.getString(INSTANCE_KEY_QUERY); 21021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 211839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, false); 212713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 213713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 214713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert @Override 2159ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onSaveInstanceState(Bundle outState) { 2169ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert super.onSaveInstanceState(outState); 2179ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // We don't save appSearchData, since we always get the value 2189ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // from the intent and the user can't change it. 219fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 22021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert outState.putString(INSTANCE_KEY_CORPUS, getCorpusName()); 221839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert outState.putString(INSTANCE_KEY_QUERY, getQuery()); 222713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 223713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 224713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private void setupFromIntent(Intent intent) { 225713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert if (DBG) Log.d(TAG, "setupFromIntent(" + intent.toUri(0) + ")"); 22621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert String corpusName = getCorpusNameFromUri(intent.getData()); 2272617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert String query = intent.getStringExtra(SearchManager.QUERY); 2282617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA); 229839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert boolean selectAll = intent.getBooleanExtra(SearchManager.EXTRA_SELECT_QUERY, false); 2302617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 232839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, selectAll); 233c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mAppSearchData = appSearchData; 2342617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23511c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert if (startedIntoCorpusSelectionDialog()) { 23641fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 2372617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 238e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood if (INTENT_ACTION_QSB_AND_HIDE_WIDGET_HINTS.equals(intent.getAction())) { 239e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood SearchWidgetProvider.hideHintsNow(getApplicationContext()); 240e83204ae5e130fed7e7f0acdbca0ed29a9bbc934Mathew Inwood } 2419ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 2429ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 24311c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert public boolean startedIntoCorpusSelectionDialog() { 24411c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert return INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(getIntent().getAction()); 24511c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert } 24611c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert 247dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert /** 248dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * Removes corpus selector intent action, so that BACK works normally after 249dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * dismissing and reopening the corpus selector. 250dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert */ 251dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private void clearStartedIntoCorpusSelectionDialog() { 252dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent oldIntent = getIntent(); 253dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (SearchActivity.INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(oldIntent.getAction())) { 254dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent newIntent = new Intent(oldIntent); 255dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert newIntent.setAction(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 256dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert setIntent(newIntent); 257dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 258dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 259dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 260fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static Uri getCorpusUri(Corpus corpus) { 261fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) return null; 262fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return new Uri.Builder() 263fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .scheme(SCHEME_CORPUS) 264fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .authority(corpus.getName()) 265fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .build(); 266fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 267fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 26821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusNameFromUri(Uri uri) { 269fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (uri == null) return null; 270fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (!SCHEME_CORPUS.equals(uri.getScheme())) return null; 27121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return uri.getAuthority(); 272fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 273fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 274fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus getCorpus(String sourceName) { 2750ccab5903ba2c64ec4cdd33dbcea91b1e279d556Bjorn Bringert if (sourceName == null) return null; 276fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Corpus corpus = getCorpora().getCorpus(sourceName); 277fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) { 278fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Log.w(TAG, "Unknown corpus " + sourceName); 2799ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert return null; 280713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 281fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return corpus; 282713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 283713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 28421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private void setCorpus(String corpusName) { 28521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert if (DBG) Log.d(TAG, "setCorpus(" + corpusName + ")"); 28621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorpus = getCorpus(corpusName); 2879ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Drawable sourceIcon; 28821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert if (mCorpus == null) { 289c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert sourceIcon = getCorpusViewFactory().getGlobalSearchIcon(); 290713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } else { 29121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert sourceIcon = mCorpus.getCorpusIcon(); 292713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 29321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mSuggestionsAdapter.setCorpus(mCorpus); 294a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator.setImageDrawable(sourceIcon); 2953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2965691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(getQuery().length() == 0); 2970484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 2980484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 29921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusName() { 30021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return mCorpus == null ? null : mCorpus.getName(); 30121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 30221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 3033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private QsbApplication getQsbApplication() { 30449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return QsbApplication.get(this); 3053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3074ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private Config getConfig() { 3084ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert return getQsbApplication().getConfig(); 3094ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 3104ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 311fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpora getCorpora() { 312fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getQsbApplication().getCorpora(); 313fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 314fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 3153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private ShortcutRepository getShortcutRepository() { 3163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return getQsbApplication().getShortcutRepository(); 3173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 319ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private SuggestionsProvider getSuggestionsProvider() { 32047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getQsbApplication().getSuggestionsProvider(); 32147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 32247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 323c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert private CorpusViewFactory getCorpusViewFactory() { 324c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert return getQsbApplication().getCorpusViewFactory(); 325185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 326185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 32749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert private VoiceSearch getVoiceSearch() { 32849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return QsbApplication.get(this).getVoiceSearch(); 32949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 33049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 331ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private Logger getLogger() { 332ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert return getQsbApplication().getLogger(); 333ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 334ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 3353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onDestroy() { 3373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onDestroy()"); 3383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onDestroy(); 33921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().unregisterDataSetObserver(mCorporaObserver); 340185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsView.setAdapter(null); // closes mSuggestionsAdapter 3413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onStop() { 3459ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onStop()"); 346f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (!mTookAction) { 347f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // TODO: This gets logged when starting other activities, e.g. by opening he search 348f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // settings, or clicking a notification in the status bar. 349f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert getLogger().logExit(getCurrentSuggestions(), getQuery().length()); 350f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 3519ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Close all open suggestion cursors. The query will be redone in onResume() 3523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // if we come back to this activity. 353185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(null); 35494e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney getQsbApplication().getShortcutRefresher().reset(); 355f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert dismissCorpusSelectionDialog(); 3563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onStop(); 3573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 360839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert protected void onRestart() { 361839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onRestart()"); 362839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert super.onRestart(); 363839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert } 364839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert 365839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert @Override 366b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert protected void onResume() { 3679ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onResume()"); 368b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert super.onResume(); 36911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert updateSuggestionsBuffered(); 370dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (!isCorpusSelectionDialogShowing()) { 371dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mQueryTextView.requestFocus(); 372dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 37311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) Debug.stopMethodTracing(); 374b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert } 375b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert 376b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert @Override 3773e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onCreateOptionsMenu(Menu menu) { 3783e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreateOptionsMenu(menu); 37926d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert SearchSettings.addSearchSettingsMenuItem(this, menu); 3803e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 3813e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 383d98911178013162737fbba74387b51d2a08b0493Amith Yamasani @Override 384d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void onWindowFocusChanged(boolean hasFocus) { 385d98911178013162737fbba74387b51d2a08b0493Amith Yamasani super.onWindowFocusChanged(hasFocus); 386d98911178013162737fbba74387b51d2a08b0493Amith Yamasani if (hasFocus) { 387d98911178013162737fbba74387b51d2a08b0493Amith Yamasani // Launch the IME after a bit 388d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mShowInputMethodTask, 0); 389d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 390d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 391d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 392713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert protected String getQuery() { 3933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert CharSequence q = mQueryTextView.getText(); 3943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return q == null ? "" : q.toString(); 3953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 398014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert * Sets the text in the query box. Does not update the suggestions. 3993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 4003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void setQuery(String query, boolean selectAll) { 4013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = false; 4023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView.setText(query); 403014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mQueryTextView.setTextSelection(selectAll); 4043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = true; 4053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 40718959800eddb7127e4fd9b24e91458d0584cc257Mathew Inwood protected void updateUi(boolean queryEmpty) { 4085691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateQueryTextView(queryEmpty); 4095691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateSearchGoButton(queryEmpty); 4105691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateVoiceSearchButton(queryEmpty); 4115691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 4125691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert 413e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateQueryTextView(boolean queryEmpty) { 414e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 41520c51f89fdba5105efdf0a37f50bf7fa013d5b8dMathew Inwood if (isSearchCorpusWeb()) { 4165691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty_google); 4175691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(null); 4185691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } else { 4195691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty); 4205691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(mCorpus.getHint()); 4215691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 422e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 423e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search); 424e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 425e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 426e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 427e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateSearchGoButton(boolean queryEmpty) { 428e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 429e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.GONE); 430e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 431e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.VISIBLE); 432e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 433e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 434e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 435e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert protected void updateVoiceSearchButton(boolean queryEmpty) { 43649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert if (queryEmpty && getVoiceSearch().shouldShowVoiceSearch(mCorpus)) { 437e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.VISIBLE); 438e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE); 439e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 440e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.GONE); 441e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(null); 442e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 443e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 444e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 44541fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert protected void showCorpusSelectionDialog() { 446f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog == null) { 447f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog = new CorpusSelectionDialog(this); 448f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOwnerActivity(this); 449dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mCorpusSelectionDialog.setOnDismissListener(new CorpusSelectorDismissListener()); 450f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOnCorpusSelectedListener(new CorpusSelectionListener()); 4512617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 452f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.show(mCorpus); 4532617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4542617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 455dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert protected boolean isCorpusSelectionDialogShowing() { 456dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert return mCorpusSelectionDialog != null && mCorpusSelectionDialog.isShowing(); 457dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 458dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 459f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert protected void dismissCorpusSelectionDialog() { 460f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog != null) { 461f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.dismiss(); 4622617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4632617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4642617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 465dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood /** 466dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood * @return true if a search was performed as a result of this click, false otherwise. 467dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood */ 468dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood protected boolean onSearchClicked(int method) { 4693a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringert String query = CharMatcher.WHITESPACE.trimAndCollapseFrom(getQuery(), ' '); 4703e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Search clicked, query=" + query); 471eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 472eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert // Don't do empty queries 473dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (TextUtils.getTrimmedLength(query) == 0) return false; 474eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 47581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 476dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (searchCorpus == null) return false; 477c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 478ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 479c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 480c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log search start 481fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getLogger().logSearch(mCorpus, method, query.length()); 482c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 483c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 484c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert SuggestionData searchShortcut = searchCorpus.createSearchShortcut(query); 485c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchShortcut != null) { 48693bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert ListSuggestionCursor cursor = new ListSuggestionCursor(query); 487c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert cursor.add(searchShortcut); 488c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getShortcutRepository().reportClick(cursor, 0); 489c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 490c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 491c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start search 492c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createSearchIntent(query, mAppSearchData); 49381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 494dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood return true; 4953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onVoiceSearchClicked() { 4983e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Voice Search clicked"); 49981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 500c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 501c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 502535931433926d342c6277034cad91143ae28b72dBjorn Bringert mTookAction = true; 503535931433926d342c6277034cad91143ae28b72dBjorn Bringert 504c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log voice search start 505c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getLogger().logVoiceSearch(searchCorpus); 506ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 507c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start voice search 508c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createVoiceSearchIntent(mAppSearchData); 50981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 51081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 51181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 51281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert /** 51381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert * Gets the corpus to use for any searches. This is the web corpus in "All" mode, 51481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert * and the selected corpus otherwise. 51581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert */ 516ca9c7b7bc0183aa1b6d160bf76597c96e70831f6Mathew Inwood protected Corpus getSearchCorpus() { 51781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (mCorpus != null) { 51881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return mCorpus; 51981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } else { 52081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus webCorpus = getCorpora().getWebCorpus(); 52181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (webCorpus == null) { 52281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "No web corpus"); 52381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 52481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return webCorpus; 52581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 526c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 527c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 528014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert /** 529014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert * Checks if the corpus used for typed searchs is the web corpus. 530014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert */ 531014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert protected boolean isSearchCorpusWeb() { 532014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert Corpus corpus = getSearchCorpus(); 533014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert return corpus != null && corpus.isWebCorpus(); 534014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 535014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 536e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert protected SuggestionCursor getCurrentSuggestions() { 537fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mSuggestionsAdapter.getCurrentSuggestions(); 538782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 539782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 5405f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert protected SuggestionCursor getCurrentSuggestions(int position) { 5415f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 5425f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (suggestions == null) { 5435f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 5445f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5455f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert int count = suggestions.getCount(); 5465f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (position < 0 || position >= count) { 5475f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert Log.w(TAG, "Invalid suggestion position " + position + ", count = " + count); 5485f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 5495f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5505f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert suggestions.moveTo(position); 5515f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return suggestions; 5525f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5535f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 5545f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert protected Set<Corpus> getCurrentIncludedCorpora() { 5555f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert Suggestions suggestions = mSuggestionsAdapter.getSuggestions(); 5565f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return suggestions == null ? null : suggestions.getIncludedCorpora(); 5575f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5585f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 55981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert protected void launchIntent(Intent intent) { 56081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (intent == null) { 56181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return; 56281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 56381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert try { 56481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert startActivity(intent); 56581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } catch (RuntimeException ex) { 56681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // Since the intents for suggestions specified by suggestion providers, 56781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // guard against them not being handled, not allowed, etc. 56881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "Failed to start " + intent.toUri(0), ex); 56981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 57081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 57181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 572fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean launchSuggestion(int position) { 5735f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(position); 5745f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (suggestions == null) return false; 5756f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert 576fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Launching suggestion " + position); 577ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 578e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert 579c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log suggestion click 5805f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert getLogger().logSuggestionClick(position, suggestions, getCurrentIncludedCorpora()); 581ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 582c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 583fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getShortcutRepository().reportClick(suggestions, position); 584c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 585c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Launch intent 58681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert suggestions.moveTo(position); 58793bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert Intent intent = SuggestionUtils.getSuggestionIntent(suggestions, mAppSearchData); 58881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 589c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 5903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 5913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 593fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionLongClicked(int position) { 594fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Long clicked on suggestion " + position); 5953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 5963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 598fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionKeyDown(int position, int keyCode, KeyEvent event) { 599782dd228e78e9294692d639597f96c26283968bbBjorn Bringert // Treat enter or search as a click 600782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) { 601fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return launchSuggestion(position); 602782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 603782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 604782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return false; 605782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 606782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6075f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert protected void refineSuggestion(int position) { 6085f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (DBG) Log.d(TAG, "query refine clicked, pos " + position); 6095f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(position); 6105f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (suggestions == null) { 6115f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 6125f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 6135f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert String query = suggestions.getSuggestionQuery(); 6145f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (TextUtils.isEmpty(query)) { 6155f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 6165f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 6175f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 6185f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Log refine click 6195f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert getLogger().logRefine(position, suggestions, getCurrentIncludedCorpora()); 6205f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 6215f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Put query + space in query text view 6225f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert String queryWithSpace = query + ' '; 6235f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert setQuery(queryWithSpace, false); 6245f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert updateSuggestions(queryWithSpace); 6255f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert mQueryTextView.requestFocus(); 6265f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 6275f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 628782dd228e78e9294692d639597f96c26283968bbBjorn Bringert protected int getSelectedPosition() { 629782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return mSuggestionsView.getSelectedPosition(); 630782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 631782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6333e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method. 6343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void hideInputMethod() { 636014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mQueryTextView.hideInputMethod(); 6373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6397b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert protected void showInputMethodForQuery() { 640014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert mQueryTextView.showInputMethod(); 6417b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6427b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 643f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood protected void onSuggestionListFocusChange(boolean focused) { 644f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood } 645f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood 646f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood protected void onQueryTextViewFocusChange(boolean focused) { 647f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood } 648f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood 6493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method when the suggestions get focus. 6513e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SuggestListFocusListener implements OnFocusChangeListener { 6533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onFocusChange(View v, boolean focused) { 6547b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Suggestions focus change, now: " + focused); 6557b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 6567b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // The suggestions list got focus, hide the input method 6577b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert hideInputMethod(); 6587b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 659f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood onSuggestionListFocusChange(focused); 6607b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6617b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6627b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6637b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert private class QueryTextViewFocusListener implements OnFocusChangeListener { 6647b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert public void onFocusChange(View v, boolean focused) { 6657b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Query focus change, now: " + focused); 6667b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 667dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert // The query box got focus, show the input method 6687b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert showInputMethodForQuery(); 6693e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 670f5e1499b48ac06de4e6e6460a7f14c3a7ac4eaddMathew Inwood onQueryTextViewFocusChange(focused); 6713e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6723e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6733e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 674e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney private int getMaxSuggestions() { 675e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney Config config = getConfig(); 676e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney return mCorpus == null 677e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney ? config.getMaxPromotedSuggestions() 678e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney : config.getMaxResultsPerSource(); 679e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney } 680e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney 6814ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private void updateSuggestionsBuffered() { 682d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.removeCallbacks(mUpdateSuggestionsTask); 6834ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert long delay = getConfig().getTypingUpdateSuggestionsDelayMillis(); 684d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mUpdateSuggestionsTask, delay); 6854ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 6864ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 6876ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert protected void updateSuggestions(String query) { 6883cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood 6893a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringert query = CharMatcher.WHITESPACE.trimLeadingFrom(query); 6902fd5aa82682f077660faa8ec60c04238026a8731Mathew Inwood if (DBG) Log.d(TAG, "getSuggestions(\""+query+"\","+mCorpus + ","+getMaxSuggestions()+")"); 6913cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood Suggestions suggestions = getSuggestionsProvider().getSuggestions( 6923cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood query, mCorpus, getMaxSuggestions()); 6933cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood 69411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert // Log start latency if this is the first suggestions update 69511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (mStarting) { 69611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert mStarting = false; 69711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String source = getIntent().getStringExtra(Search.SOURCE); 69811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert int latency = mStartLatencyTracker.getLatency(); 6993cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood getLogger().logStart(latency, source, mCorpus, suggestions.getExpectedCorpora()); 700b5560dbe16a8fb3148b0fb24c73836bf2e84dd61Mathew Inwood getQsbApplication().onStartupComplete(); 70111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 70211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 703185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(suggestions); 7043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 706014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert /** 707014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert * If the input method is in fullscreen mode, and the selector corpus 708014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert * is All or Web, use the web search suggestions as completions. 709014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert */ 710014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert protected void updateInputMethodSuggestions() { 711014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 712014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert if (imm == null || !imm.isFullscreenMode()) return; 713014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert Suggestions suggestions = mSuggestionsAdapter.getSuggestions(); 714014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert if (suggestions == null) return; 715014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert SuggestionCursor cursor = suggestions.getPromoted(); 716014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert if (cursor == null) return; 717014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert CompletionInfo[] completions = webSuggestionsToCompletions(cursor); 718014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert if (DBG) Log.d(TAG, "displayCompletions(" + Arrays.toString(completions) + ")"); 719014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert imm.displayCompletions(mQueryTextView, completions); 720014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 721014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 722014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert private CompletionInfo[] webSuggestionsToCompletions(SuggestionCursor cursor) { 723014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert int count = cursor.getCount(); 724014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert ArrayList<CompletionInfo> completions = new ArrayList<CompletionInfo>(count); 72520c51f89fdba5105efdf0a37f50bf7fa013d5b8dMathew Inwood boolean usingWebCorpus = isSearchCorpusWeb(); 726014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert for (int i = 0; i < count; i++) { 727014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert cursor.moveTo(i); 72820c51f89fdba5105efdf0a37f50bf7fa013d5b8dMathew Inwood if (!usingWebCorpus || cursor.isWebSearchSuggestion()) { 729014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert String text1 = cursor.getSuggestionText1(); 730014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert completions.add(new CompletionInfo(i, i, text1)); 731014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 732014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 733014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert return completions.toArray(new CompletionInfo[completions.size()]); 734014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 735014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 7367be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean forwardKeyToQueryTextView(int keyCode, KeyEvent event) { 7377be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (!event.isSystem() && !isDpadKey(keyCode)) { 7387be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (DBG) Log.d(TAG, "Forwarding key to query box: " + event); 7397be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (mQueryTextView.requestFocus()) { 7407be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return mQueryTextView.dispatchKeyEvent(event); 7417be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7427be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7437be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 7447be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7457be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 7467be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean isDpadKey(int keyCode) { 7477be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert switch (keyCode) { 7487be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_UP: 7497be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_DOWN: 7507be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_LEFT: 7517be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_RIGHT: 7527be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_CENTER: 7537be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return true; 7547be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert default: 7557be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 7567be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7577be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7587be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 7593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Filters the suggestions list when the search text changes. 7613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchTextWatcher implements TextWatcher { 7633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void afterTextChanged(Editable s) { 764e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert boolean empty = s.length() == 0; 765e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (empty != mQueryWasEmpty) { 766e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryWasEmpty = empty; 7675691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(empty); 768e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 7693e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (mUpdateSuggestions) { 7704ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestionsBuffered(); 7713e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7723e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7733e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7743e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void beforeTextChanged(CharSequence s, int start, int count, int after) { 7753e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7763e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7773e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onTextChanged(CharSequence s, int start, int before, int count) { 7783e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7793e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7803e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7813e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Handles non-text keys in the query text view. 7833e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class QueryTextViewKeyListener implements View.OnKeyListener { 7853e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onKey(View view, int keyCode, KeyEvent event) { 7863e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // Handle IME search action key 7873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { 788d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // if no action was taken, consume the key event so that the keyboard 789d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // remains on screen. 790dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood return !onSearchClicked(Logger.SEARCH_METHOD_KEYBOARD); 7913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 7933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 796782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 797782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the search and voice search buttons, 798782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * by refocusing to EditText. 799782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 800782dd228e78e9294692d639597f96c26283968bbBjorn Bringert private class ButtonsKeyListener implements View.OnKeyListener { 801782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 8027be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 803782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 804782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 805782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 806782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 807782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the suggestions list view. 808782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 809713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private class SuggestionsViewKeyListener implements View.OnKeyListener { 810782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 811782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (event.getAction() == KeyEvent.ACTION_DOWN) { 812fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert int position = getSelectedPosition(); 813fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (onSuggestionKeyDown(position, keyCode, event)) { 814839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert return true; 815782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 816782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 8177be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 818782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 819782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 820782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 821145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert private class InputMethodCloser implements SuggestionsView.OnScrollListener { 822145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 823145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 824145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert int totalItemCount) { 825145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 826145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 827145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScrollStateChanged(AbsListView view, int scrollState) { 828185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert hideInputMethod(); 829185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 830185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 831185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 832185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert private class ClickHandler implements SuggestionClickListener { 833fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onSuggestionClicked(int position) { 834fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert launchSuggestion(position); 8353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 837fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean onSuggestionLongClicked(int position) { 838fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return SearchActivity.this.onSuggestionLongClicked(position); 839713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 840145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 841145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onSuggestionQueryRefineClicked(int position) { 8425f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert refineSuggestion(position); 843145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 8443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8472617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the source selector. 8483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchGoButtonClickListener implements View.OnClickListener { 8503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 851ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert onSearchClicked(Logger.SEARCH_METHOD_BUTTON); 8523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8562617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the search button. 8572617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert */ 858fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private class CorpusIndicatorClickListener implements View.OnClickListener { 8592617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert public void onClick(View view) { 86041fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 8612617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 862f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 863f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 864dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private class CorpusSelectorDismissListener implements DialogInterface.OnDismissListener { 865dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert public void onDismiss(DialogInterface dialog) { 866dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (DBG) Log.d(TAG, "Corpus selector dismissed"); 867dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert clearStartedIntoCorpusSelectionDialog(); 868dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 869dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 870dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 871f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private class CorpusSelectionListener 872f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert implements CorpusSelectionDialog.OnCorpusSelectedListener { 87321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onCorpusSelected(String corpusName) { 87421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 875f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert updateSuggestions(getQuery()); 876f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mQueryTextView.requestFocus(); 877dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert showInputMethodForQuery(); 878f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 8792617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 8802617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 8812617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert /** 8823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Listens for clicks on the voice search button. 8833e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class VoiceSearchButtonClickListener implements View.OnClickListener { 8853e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 8863e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert onVoiceSearchClicked(); 8873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 89021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private class CorporaObserver extends DataSetObserver { 89121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert @Override 89221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onChanged() { 89321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(getCorpusName()); 89421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert updateSuggestions(getQuery()); 89521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 89621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 89721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 898014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert private class SuggestionsObserver extends DataSetObserver { 899014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert @Override 900014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert public void onChanged() { 901014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert updateInputMethodSuggestions(); 902014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 903014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 904014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 9053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert} 906