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; 293bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringertimport android.app.AlertDialog; 303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.SearchManager; 31dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringertimport android.content.DialogInterface; 323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.content.Intent; 3321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringertimport android.database.DataSetObserver; 34fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.net.Uri; 353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Bundle; 3611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport android.os.Debug; 374ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringertimport android.os.Handler; 383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextUtils; 393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.util.Log; 403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.Menu; 413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View; 42fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringertimport android.widget.Toast; 433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport java.io.File; 45dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringertimport java.util.ArrayList; 464572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwoodimport java.util.Collection; 47b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertimport java.util.List; 485f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringertimport java.util.Set; 49ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/** 513e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * The main activity for Quick Search Box. Shows the search UI. 523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class SearchActivity extends Activity { 553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 56754cb6b769c5955fc707a6c5ab6689b64df102b3Mathew Inwood private static final boolean DBG = false; 570484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private static final String TAG = "QSB.SearchActivity"; 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 6448ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert private static final String INTENT_EXTRA_TRACE_START_UP = "trace_start_up"; 6548ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert 669ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Keys for the saved instance state. 67fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String INSTANCE_KEY_CORPUS = "corpus"; 68839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert private static final String INSTANCE_KEY_QUERY = "query"; 69713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 7071f9f8ccd3c12d7d48e2fee4c55cd57e1970b797Bjorn Bringert private static final String ACTIVITY_HELP_CONTEXT = "search"; 7171f9f8ccd3c12d7d48e2fee4c55cd57e1970b797Bjorn Bringert 7248ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert private boolean mTraceStartUp; 73f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // Measures time from for last onCreate()/onNewIntent() call. 74f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private LatencyTracker mStartLatencyTracker; 7598cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood // Measures time spent inside onCreate() 7698cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private LatencyTracker mOnCreateTracker; 7798cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private int mOnCreateLatency; 78ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // Whether QSB is starting. True between the calls to onCreate()/onNewIntent() and onResume(). 79ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mStarting; 80ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // True if the user has taken some action, e.g. launching a search, voice search, 81ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // or suggestions, since QSB was last started. 82ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mTookAction; 83ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 847010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert private SearchActivityView mSearchActivityView; 85185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 8621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private CorporaObserver mCorporaObserver; 8721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 882617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert private Bundle mAppSearchData; 893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 90d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Handler mHandler = new Handler(); 91d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mUpdateSuggestionsTask = new Runnable() { 924ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert public void run() { 937f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert updateSuggestions(); 944ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 954ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert }; 964ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 97d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mShowInputMethodTask = new Runnable() { 98d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void run() { 997010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.showInputMethodForQuery(); 100d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 101d98911178013162737fbba74387b51d2a08b0493Amith Yamasani }; 102d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 1032607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood private OnDestroyListener mDestroyListener; 1042607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 1053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** Called when the activity is first created. */ 1063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 1073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onCreate(Bundle savedInstanceState) { 10848ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert mTraceStartUp = getIntent().hasExtra(INTENT_EXTRA_TRACE_START_UP); 10948ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert if (mTraceStartUp) { 11048ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert String traceFile = new File(getDir("traces", 0), "qsb-start.trace").getAbsolutePath(); 11148ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert Log.i(TAG, "Writing start-up trace to " + traceFile); 11248ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert Debug.startMethodTracing(traceFile); 11348ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert } 114ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onCreate()"); 1163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreate(savedInstanceState); 117713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 118c953ef06f0fc1fb4157fe67aa145cf702ee204d0Narayan Kamath // This forces the HTTP request to check the users domain to be 119c953ef06f0fc1fb4157fe67aa145cf702ee204d0Narayan Kamath // sent as early as possible. 120c953ef06f0fc1fb4157fe67aa145cf702ee204d0Narayan Kamath QsbApplication.get(this).getSearchBaseUrlHelper(); 121c953ef06f0fc1fb4157fe67aa145cf702ee204d0Narayan Kamath 1225880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert mSearchActivityView = setupContentView(); 123aa7d79792baca59eb7afe00ea27abc5176ddd34bMathew Inwood 124fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood if (getConfig().showScrollingSuggestions()) { 125f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood mSearchActivityView.setMaxPromotedSuggestions(getConfig().getMaxPromotedSuggestions()); 126fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood } else { 127fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood mSearchActivityView.limitSuggestionsToViewHeight(); 128fdb80c2962c88ac62dcd7ee7f2fab1857b61506bMathew Inwood } 129f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood if (getConfig().showScrollingResults()) { 1307a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mSearchActivityView.setMaxPromotedResults(getConfig().getMaxPromotedResults()); 131f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood } else { 132f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood mSearchActivityView.limitResultsToViewHeight(); 133f5a8912d5da80378d38b667eba4aaa0555aea7bdMathew Inwood } 134848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 1357010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSearchClickListener(new SearchActivityView.SearchClickListener() { 1367010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public boolean onSearchClicked(int method) { 1377010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return SearchActivity.this.onSearchClicked(method); 1387010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1397010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 1402617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 1417010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setQueryListener(new SearchActivityView.QueryListener() { 1427010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public void onQueryChanged() { 1437010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert updateSuggestionsBuffered(); 1447010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1457010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 146782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 1477010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSuggestionClickListener(new ClickHandler()); 1487be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 1497010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setVoiceSearchButtonClickListener(new View.OnClickListener() { 1507010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert public void onClick(View view) { 1517010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert onVoiceSearchClicked(); 1527010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert } 1537010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert }); 1549ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 155e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood View.OnClickListener finishOnClick = new View.OnClickListener() { 1569e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood public void onClick(View v) { 1579e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood finish(); 1589e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood } 159e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood }; 160e833f84eee7ab575c8d53dec9b133fa5de9c7e6dMathew Inwood mSearchActivityView.setExitClickListener(finishOnClick); 1619e46c057d7f88d2a899e124f96d266c54250bb45Mathew Inwood 1629ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // First get setup from intent 1639ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Intent intent = getIntent(); 1649ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1659ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Then restore any saved instance state 1669ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert restoreInstanceState(savedInstanceState); 1679ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 168713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // Do this at the end, to avoid updating the list view when setSource() 169713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // is called. 1707010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.start(); 17121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 17221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorporaObserver = new CorporaObserver(); 17321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().registerDataSetObserver(mCorporaObserver); 17498cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood recordOnCreateDone(); 1759ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 176713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1775880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected SearchActivityView setupContentView() { 1786ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert setContentView(R.layout.search_activity); 1795880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert return (SearchActivityView) findViewById(R.id.search_activity_view); 1805880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert } 1815880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert 1825880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected SearchActivityView getSearchActivityView() { 1835880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert return mSearchActivityView; 1846ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert } 1856ae65b29ce9313a4f0624ef825f75151db5ec2feBjorn Bringert 1869ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert @Override 1879ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onNewIntent(Intent intent) { 188839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onNewIntent()"); 189ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1909ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setIntent(intent); 1919ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1929ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 1939ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 194ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private void recordStartTime() { 195f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mStartLatencyTracker = new LatencyTracker(); 19698cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood mOnCreateTracker = new LatencyTracker(); 197ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mStarting = true; 198ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = false; 199ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 200ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 20198cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood private void recordOnCreateDone() { 20298cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood mOnCreateLatency = mOnCreateTracker.getLatency(); 20398cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood } 20498cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood 2059ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void restoreInstanceState(Bundle savedInstanceState) { 2069ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (savedInstanceState == null) return; 207fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = savedInstanceState.getString(INSTANCE_KEY_CORPUS); 208839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert String query = savedInstanceState.getString(INSTANCE_KEY_QUERY); 20921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 210839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, false); 211713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 212713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 213713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert @Override 2149ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onSaveInstanceState(Bundle outState) { 2159ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert super.onSaveInstanceState(outState); 2169ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // We don't save appSearchData, since we always get the value 2179ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // from the intent and the user can't change it. 218fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 21921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert outState.putString(INSTANCE_KEY_CORPUS, getCorpusName()); 220839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert outState.putString(INSTANCE_KEY_QUERY, getQuery()); 221713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 222713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 223713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private void setupFromIntent(Intent intent) { 224713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert if (DBG) Log.d(TAG, "setupFromIntent(" + intent.toUri(0) + ")"); 22521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert String corpusName = getCorpusNameFromUri(intent.getData()); 2262617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert String query = intent.getStringExtra(SearchManager.QUERY); 2272617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA); 228839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert boolean selectAll = intent.getBooleanExtra(SearchManager.EXTRA_SELECT_QUERY, false); 2292617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 231839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert setQuery(query, selectAll); 232c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mAppSearchData = appSearchData; 2332617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23411c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert if (startedIntoCorpusSelectionDialog()) { 2350a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.showCorpusSelectionDialog(); 2362617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 2379ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 2389ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 23911c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert public boolean startedIntoCorpusSelectionDialog() { 24011c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert return INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(getIntent().getAction()); 24111c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert } 24211c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert 243dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert /** 244dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * Removes corpus selector intent action, so that BACK works normally after 245dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * dismissing and reopening the corpus selector. 246dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert */ 2470a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood public void clearStartedIntoCorpusSelectionDialog() { 248dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent oldIntent = getIntent(); 249dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (SearchActivity.INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(oldIntent.getAction())) { 250dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent newIntent = new Intent(oldIntent); 251dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert newIntent.setAction(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 252dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert setIntent(newIntent); 253dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 254dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 255dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 256fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static Uri getCorpusUri(Corpus corpus) { 257fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) return null; 258fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return new Uri.Builder() 259fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .scheme(SCHEME_CORPUS) 260fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .authority(corpus.getName()) 261fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .build(); 262fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 263fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 26421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusNameFromUri(Uri uri) { 265fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (uri == null) return null; 266fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (!SCHEME_CORPUS.equals(uri.getScheme())) return null; 26721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return uri.getAuthority(); 268fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 269fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 2700a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private Corpus getCorpus() { 2710a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return mSearchActivityView.getCorpus(); 272713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 273713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 2740a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private String getCorpusName() { 2750a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return mSearchActivityView.getCorpusName(); 276f165f2d6c6f8173b94937ae3202f0b638348dffdBjorn Bringert } 277f165f2d6c6f8173b94937ae3202f0b638348dffdBjorn Bringert 2780a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood private void setCorpus(String name) { 2790a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.setCorpus(name); 28021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 28121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 2823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private QsbApplication getQsbApplication() { 28349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return QsbApplication.get(this); 2843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 2853e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2864ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private Config getConfig() { 2874ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert return getQsbApplication().getConfig(); 2884ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 2894ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 29096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert protected SearchSettings getSettings() { 29196fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return getQsbApplication().getSettings(); 29296fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert } 29396fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 294b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private Corpora getCorpora() { 295b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getCorpora(); 296fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 297fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 298b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private CorpusRanker getCorpusRanker() { 299b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getCorpusRanker(); 3003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 302b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private ShortcutRepository getShortcutRepository() { 303b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getShortcutRepository(); 304848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 305848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 306b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private SuggestionsProvider getSuggestionsProvider() { 307b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert return getQsbApplication().getSuggestionsProvider(); 30847d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 30947d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 310ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private Logger getLogger() { 311ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert return getQsbApplication().getLogger(); 312ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 313ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 3142607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood @VisibleForTesting 3152607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood public void setOnDestroyListener(OnDestroyListener l) { 3162607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood mDestroyListener = l; 3172607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 3182607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 3193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onDestroy() { 3213e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onDestroy()"); 32221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().unregisterDataSetObserver(mCorporaObserver); 3237010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.destroy(); 3242607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood super.onDestroy(); 3252607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood if (mDestroyListener != null) { 3262607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood mDestroyListener.onDestroyed(); 3272607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 3283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onStop() { 3329ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onStop()"); 333f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (!mTookAction) { 334848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani // TODO: This gets logged when starting other activities, e.g. by opening the search 335f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // settings, or clicking a notification in the status bar. 336aa7d79792baca59eb7afe00ea27abc5176ddd34bMathew Inwood // TODO we should log both sets of suggestions in 2-pane mode 337f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert getLogger().logExit(getCurrentSuggestions(), getQuery().length()); 338f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 3399ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Close all open suggestion cursors. The query will be redone in onResume() 3403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // if we come back to this activity. 3417010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.clearSuggestions(); 34294e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney getQsbApplication().getShortcutRefresher().reset(); 3430a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.onStop(); 3443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onStop(); 3453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3482e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani protected void onPause() { 3492e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani if (DBG) Log.d(TAG, "onPause()"); 3502e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani mSearchActivityView.onPause(); 3512e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani super.onPause(); 3522e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani } 3532e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani 3542e684983c6a20faa209e42f6c63337cfcb34fc71Amith Yamasani @Override 355839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert protected void onRestart() { 356839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert if (DBG) Log.d(TAG, "onRestart()"); 357839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert super.onRestart(); 358839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert } 359839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert 360839a9fd2828f37c9dc8345f93aefa5b8ad2f857fBjorn Bringert @Override 361b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert protected void onResume() { 3629ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onResume()"); 363b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert super.onResume(); 36411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert updateSuggestionsBuffered(); 3650a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood mSearchActivityView.onResume(); 36648ced2f683491d07d892ec81f88fe2e26f9207c2Bjorn Bringert if (mTraceStartUp) Debug.stopMethodTracing(); 367b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert } 368b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert 369b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert @Override 37073a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert public boolean onPrepareOptionsMenu(Menu menu) { 37173a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert // Since the menu items are dynamic, we recreate the menu every time. 37273a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert menu.clear(); 37373a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert createMenuItems(menu, true); 37496fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return true; 37596fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert } 37696fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 37773a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert public void createMenuItems(Menu menu, boolean showDisabled) { 37873a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert getSettings().addMenuItems(menu, showDisabled); 37971f9f8ccd3c12d7d48e2fee4c55cd57e1970b797Bjorn Bringert getQsbApplication().getHelp().addHelpMenuItem(menu, ACTIVITY_HELP_CONTEXT); 3805eee22a4ec6fc45deb9706ba535039ccae51b90aBjorn Bringert } 3815eee22a4ec6fc45deb9706ba535039ccae51b90aBjorn Bringert 38296fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert @Override 383d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void onWindowFocusChanged(boolean hasFocus) { 384d98911178013162737fbba74387b51d2a08b0493Amith Yamasani super.onWindowFocusChanged(hasFocus); 385d98911178013162737fbba74387b51d2a08b0493Amith Yamasani if (hasFocus) { 386d98911178013162737fbba74387b51d2a08b0493Amith Yamasani // Launch the IME after a bit 387d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mShowInputMethodTask, 0); 388d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 389d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 390d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 391713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert protected String getQuery() { 3927010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return mSearchActivityView.getQuery(); 3933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3957010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert protected void setQuery(String query, boolean selectAll) { 3967010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setQuery(query, selectAll); 397e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 398e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 3990a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood public CorpusSelectionDialog getCorpusSelectionDialog() { 4000a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood CorpusSelectionDialog dialog = createCorpusSelectionDialog(); 4010a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood dialog.setOwnerActivity(this); 4020a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood dialog.setOnDismissListener(new CorpusSelectorDismissListener()); 4030a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood return dialog; 4042617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4052617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 40623db3f9877e691568fe2c955fd9d4f48a2eb937aMathew Inwood protected CorpusSelectionDialog createCorpusSelectionDialog() { 40796fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return new CorpusSelectionDialog(this, getSettings()); 40835c43805a450c17d5fc5e27dc073edc6e2cd7320Amith Yamasani } 40935c43805a450c17d5fc5e27dc073edc6e2cd7320Amith Yamasani 410dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood /** 411dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood * @return true if a search was performed as a result of this click, false otherwise. 412dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood */ 413dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood protected boolean onSearchClicked(int method) { 4143a7125b39b72f7417684c4d3040abeb4a81bd6b3Bjorn Bringert String query = CharMatcher.WHITESPACE.trimAndCollapseFrom(getQuery(), ' '); 4153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Search clicked, query=" + query); 416eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 417eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert // Don't do empty queries 418dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (TextUtils.getTrimmedLength(query) == 0) return false; 419eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 42081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 421dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (searchCorpus == null) return false; 422c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 423ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 424c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 425c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log search start 4260a73d81f02118d0343d3f1c9219a8354466f72b3Mathew Inwood getLogger().logSearch(getCorpus(), method, query.length()); 427c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 428c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start search 4299d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert startSearch(searchCorpus, query); 4309d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert return true; 4319d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert } 4329d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 4339d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert protected void startSearch(Corpus searchCorpus, String query) { 434c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createSearchIntent(query, mAppSearchData); 43581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 4363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onVoiceSearchClicked() { 4393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Voice Search clicked"); 44081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 441c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 442c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 443535931433926d342c6277034cad91143ae28b72dBjorn Bringert mTookAction = true; 444535931433926d342c6277034cad91143ae28b72dBjorn Bringert 445c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log voice search start 446c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getLogger().logVoiceSearch(searchCorpus); 447ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 448c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start voice search 449c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createVoiceSearchIntent(mAppSearchData); 45081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 45181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 45281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 453ca9c7b7bc0183aa1b6d160bf76597c96e70831f6Mathew Inwood protected Corpus getSearchCorpus() { 4547010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert return mSearchActivityView.getSearchCorpus(); 455014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert } 456014e0d0c0a5102b7cc1c5576a3af25a646731dd0Bjorn Bringert 457e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert protected SuggestionCursor getCurrentSuggestions() { 458fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood return mSearchActivityView.getCurrentPromotedSuggestions(); 459782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 460782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 4617a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected SuggestionPosition getCurrentSuggestions(SuggestionsAdapter<?> adapter, long id) { 4627a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition pos = adapter.getSuggestion(id); 4637a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (pos == null) { 4647a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return null; 4657a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood } 4667a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionCursor suggestions = pos.getCursor(); 4677a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood int position = pos.getPosition(); 4685f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (suggestions == null) { 4695f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 4705f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4715f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert int count = suggestions.getCount(); 4725f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (position < 0 || position >= count) { 4735f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert Log.w(TAG, "Invalid suggestion position " + position + ", count = " + count); 4745f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return null; 4755f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4765f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert suggestions.moveTo(position); 4777a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return pos; 4785f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4795f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 4805f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert protected Set<Corpus> getCurrentIncludedCorpora() { 4817010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert Suggestions suggestions = mSearchActivityView.getSuggestions(); 482848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani return suggestions == null ? null : suggestions.getIncludedCorpora(); 4835f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 4845f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 48581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert protected void launchIntent(Intent intent) { 48613b4f2dc4b339790c2b9b0220be47c8e77fd61eaMathew Inwood if (DBG) Log.d(TAG, "launchIntent " + intent); 48781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (intent == null) { 48881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return; 48981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 49081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert try { 49181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert startActivity(intent); 49281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } catch (RuntimeException ex) { 49381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // Since the intents for suggestions specified by suggestion providers, 49481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // guard against them not being handled, not allowed, etc. 49581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "Failed to start " + intent.toUri(0), ex); 49681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 49781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 49881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 4997a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood private boolean launchSuggestion(SuggestionsAdapter<?> adapter, long id) { 5007a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5017a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return false; 5026f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert 5037a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "Launching suggestion " + id); 504ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 505e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert 506c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log suggestion click 5077a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 508c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_LAUNCH); 509ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 510c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 5117a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getShortcutRepository().reportClick(suggestion.getCursor(), suggestion.getPosition()); 512c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 513c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Launch intent 5147a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood launchSuggestion(suggestion.getCursor(), suggestion.getPosition()); 5159d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 5169d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert return true; 5179d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert } 5189d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert 5199d731c0bae275ee9b1c87b679820259c18cc68c8Bjorn Bringert protected void launchSuggestion(SuggestionCursor suggestions, int position) { 52081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert suggestions.moveTo(position); 52193bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert Intent intent = SuggestionUtils.getSuggestionIntent(suggestions, mAppSearchData); 52281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 5233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5253bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert protected void removeFromHistoryClicked(final SuggestionsAdapter<?> adapter, 5263bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert final long id) { 5273bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5283bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert if (suggestion == null) return; 5293bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert CharSequence title = suggestion.getSuggestionText1(); 5303bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert AlertDialog dialog = new AlertDialog.Builder(this) 5313bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert .setTitle(title) 5323bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert .setMessage(R.string.remove_from_history) 5333bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert .setPositiveButton(android.R.string.ok, 5343bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert new DialogInterface.OnClickListener() { 5353bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert public void onClick(DialogInterface dialog, int which) { 5363bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert // TODO: what if the suggestions have changed? 5373bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert removeFromHistory(adapter, id); 5383bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert } 5393bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert }) 5403bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert .setNegativeButton(android.R.string.cancel, null) 5413bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert .create(); 5423bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert dialog.show(); 5433bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert } 5443bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert 5457a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void removeFromHistory(SuggestionsAdapter<?> adapter, long id) { 5467a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5477a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return; 5487a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood removeFromHistory(suggestion.getCursor(), suggestion.getPosition()); 549fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert // TODO: Log to event log? 550fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 551fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 552fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeFromHistory(SuggestionCursor suggestions, int position) { 553fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert removeShortcut(suggestions, position); 554fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert removeFromHistoryDone(true); 555fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 556fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 557fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeFromHistoryDone(boolean ok) { 558fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert Log.i(TAG, "Removed query from history, success=" + ok); 559fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert updateSuggestionsBuffered(); 560fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (!ok) { 561fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert Toast.makeText(this, R.string.remove_from_history_failed, Toast.LENGTH_SHORT).show(); 562fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 563fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 564fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 565fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert protected void removeShortcut(SuggestionCursor suggestions, int position) { 566fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (suggestions.isSuggestionShortcut()) { 567fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert if (DBG) Log.d(TAG, "Removing suggestion " + position + " from shortcuts"); 568fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert getShortcutRepository().removeFromHistory(suggestions, position); 569fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 570fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert } 571fb8ce18922dae59db424fce906b5c113797fe81eBjorn Bringert 5727a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void clickedQuickContact(SuggestionsAdapter<?> adapter, long id) { 5737a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5747a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) return; 575c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 5767a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "Used suggestion " + suggestion.getPosition()); 577c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert mTookAction = true; 578c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 579c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert // Log suggestion click 5807a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 581c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_QUICK_CONTACT); 582c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 583c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert // Create shortcut 5847a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getShortcutRepository().reportClick(suggestion.getCursor(), suggestion.getPosition()); 585c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert } 586c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert 5877a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood protected void refineSuggestion(SuggestionsAdapter<?> adapter, long id) { 5887a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (DBG) Log.d(TAG, "query refine clicked, pos " + id); 5897a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood SuggestionPosition suggestion = getCurrentSuggestions(adapter, id); 5907a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood if (suggestion == null) { 5915f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 5925f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5937a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood String query = suggestion.getSuggestionQuery(); 5945f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert if (TextUtils.isEmpty(query)) { 5955f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert return; 5965f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert } 5975f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 5985f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Log refine click 5997a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood getLogger().logSuggestionClick(id, suggestion.getCursor(), getCurrentIncludedCorpora(), 600c020c1844b0fb3a825e8a6fa6ad96288bc432fbcBjorn Bringert Logger.SUGGESTION_CLICK_TYPE_REFINE); 6015f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert 6025f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert // Put query + space in query text view 6035f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert String queryWithSpace = query + ' '; 6045f71d5746ec042ad2e5c1eee8c83514f92534372Bjorn Bringert setQuery(queryWithSpace, false); 605dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert updateSuggestions(); 6067010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.focusQueryTextView(); 6073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6094ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private void updateSuggestionsBuffered() { 6107f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestionsBuffered()"); 611d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.removeCallbacks(mUpdateSuggestionsTask); 6124ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert long delay = getConfig().getTypingUpdateSuggestionsDelayMillis(); 613d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mUpdateSuggestionsTask, delay); 6144ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 6154ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 616b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert private void gotSuggestions(Suggestions suggestions) { 61711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (mStarting) { 61811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert mStarting = false; 61911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String source = getIntent().getStringExtra(Search.SOURCE); 62011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert int latency = mStartLatencyTracker.getLatency(); 62198cbee7f6266509a0805b3fef060f01caaef69e3Mathew Inwood getLogger().logStart(mOnCreateLatency, latency, source, getCorpus(), 622848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani suggestions == null ? null : suggestions.getExpectedCorpora()); 623b5560dbe16a8fb3148b0fb24c73836bf2e84dd61Mathew Inwood getQsbApplication().onStartupComplete(); 62411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 625848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 626848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 6276859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert private void getCorporaToQuery(Consumer<List<Corpus>> consumer) { 628dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert Corpus corpus = getCorpus(); 629dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert if (corpus == null) { 630dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert getCorpusRanker().getCorporaInAll(Consumers.createAsyncConsumer(mHandler, consumer)); 631dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert } else { 632dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert List<Corpus> corpora = new ArrayList<Corpus>(); 633dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 634dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert if (searchCorpus != null) corpora.add(searchCorpus); 635dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert consumer.consume(corpora); 636dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert } 6374572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood } 6384572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood 639b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert protected void getShortcutsForQuery(String query, Collection<Corpus> corporaToQuery, 640b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert final Suggestions suggestions) { 641b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert ShortcutRepository shortcutRepo = getShortcutRepository(); 642b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert if (shortcutRepo == null) return; 643e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood if (query.length() == 0 && !getConfig().showShortcutsForZeroQuery()) { 644e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood return; 645e15fe38f0142174d223bfda0cd87d1a749a85facMathew Inwood } 646b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert Consumer<ShortcutCursor> consumer = Consumers.createAsyncCloseableConsumer(mHandler, 647b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert new Consumer<ShortcutCursor>() { 648b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert public boolean consume(ShortcutCursor shortcuts) { 649b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert suggestions.setShortcuts(shortcuts); 650b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert return true; 651b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert } 652b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert }); 6538749e77dddec9e7984ee86a7be6f5ba4fce44362Bjorn Bringert shortcutRepo.getShortcutsForQuery(query, corporaToQuery, 6548749e77dddec9e7984ee86a7be6f5ba4fce44362Bjorn Bringert getSettings().allowWebSearchShortcuts(), consumer); 655b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert } 65611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 657dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert public void updateSuggestions() { 6587f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestions()"); 6597f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert final String query = CharMatcher.WHITESPACE.trimLeadingFrom(getQuery()); 6604572856ac85bb53ea06e65d00beebdf336af9b27Mathew Inwood getQsbApplication().getSourceTaskExecutor().cancelPendingTasks(); 6616859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert getCorporaToQuery(new Consumer<List<Corpus>>(){ 6626859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert @Override 6636859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert public boolean consume(List<Corpus> corporaToQuery) { 6646859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert updateSuggestions(query, corporaToQuery); 6656859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert return true; 6666859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert } 6676859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert }); 6686859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert } 669b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert 6706859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert protected void updateSuggestions(String query, List<Corpus> corporaToQuery) { 6717f5ff91319a8433abd92f3e3179158e38391e159Bjorn Bringert if (DBG) Log.d(TAG, "updateSuggestions(\"" + query+"\"," + corporaToQuery + ")"); 672b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert Suggestions suggestions = getSuggestionsProvider().getSuggestions( 673b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert query, corporaToQuery); 674b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert getShortcutsForQuery(query, corporaToQuery, suggestions); 675b42184f1e6a1b7bb22797ff92cae696753aca770Bjorn Bringert 676b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert // Log start latency if this is the first suggestions update 677b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert gotSuggestions(suggestions); 678b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert 6795880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert showSuggestions(suggestions); 6805880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert } 6815880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert 6825880fdc4f6fef3c9b5b95a49a0f23c37c69f89d5Bjorn Bringert protected void showSuggestions(Suggestions suggestions) { 6837010c51b51c97fa43d7b24d2158ecbc1d064e0a6Bjorn Bringert mSearchActivityView.setSuggestions(suggestions); 684185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 685185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 686185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert private class ClickHandler implements SuggestionClickListener { 687848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 6887a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQuickContactClicked(SuggestionsAdapter<?> adapter, long id) { 6897a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood clickedQuickContact(adapter, id); 690848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 6913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6927a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionClicked(SuggestionsAdapter<?> adapter, long id) { 6937a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood launchSuggestion(adapter, id); 694848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 695145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 6967a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionRemoveFromHistoryClicked(SuggestionsAdapter<?> adapter, long id) { 6973bcf2de0b52d088a928f0efe962608baa9cc1e39Bjorn Bringert removeFromHistoryClicked(adapter, id); 698848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 6993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7007a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQueryRefineClicked(SuggestionsAdapter<?> adapter, long id) { 7017a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood refineSuggestion(adapter, id); 7022617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 703f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 704f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 705dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private class CorpusSelectorDismissListener implements DialogInterface.OnDismissListener { 706dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert public void onDismiss(DialogInterface dialog) { 707dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (DBG) Log.d(TAG, "Corpus selector dismissed"); 708dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert clearStartedIntoCorpusSelectionDialog(); 709dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 710dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 711dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 71221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private class CorporaObserver extends DataSetObserver { 71321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert @Override 71421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onChanged() { 71521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(getCorpusName()); 716dfc1772caf35942837d83331d787eb10734c37cbBjorn Bringert updateSuggestions(); 71721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 71821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 71921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 7202607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood public interface OnDestroyListener { 7212607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood void onDestroyed(); 7222607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood } 7232607687d72deb8e06329597ab8bffcca9c746153Mathew Inwood 7243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert} 725