1fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert/* 2fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Copyright (C) 2010 The Android Open Source Project 3fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 4fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 5fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * you may not use this file except in compliance with the License. 6fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * You may obtain a copy of the License at 7fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 8fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 9fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 10fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Unless required by applicable law or agreed to in writing, software 11fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 12fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * See the License for the specific language governing permissions and 14fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * limitations under the License. 15fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 16fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 17fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertpackage com.android.quicksearchbox; 18fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 19fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 202353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringertimport com.android.quicksearchbox.util.Util; 212353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert 22fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.content.Context; 23fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.content.Intent; 24fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.graphics.drawable.Drawable; 25fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.net.Uri; 26fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.os.Bundle; 27848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasaniimport android.util.Log; 28dfabb7cfae91f6af3b5a9a9584cdec5557d1fcebDianne Hackbornimport android.util.Patterns; 29fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.webkit.URLUtil; 30fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 31883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringertimport java.util.ArrayList; 3213ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringertimport java.util.List; 3372f9b08ce84d0e13daf2d1c112d4e6d1d3ada045Bjorn Bringertimport java.util.concurrent.Executor; 34883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert 35fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert/** 36fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * The web search source. 37fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 38f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringertpublic class WebCorpus extends MultiSourceCorpus { 39848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani private static final String TAG = "QSB.WebCorpus"; 40848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani private static final boolean DBG = false; 41fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 42fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String WEB_CORPUS_NAME = "web"; 43fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 4496fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert private final SearchSettings mSettings; 4596fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 46848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani private Source mWebSearchSource; 47883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert 4813ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert private final Source mBrowserSource; 4913ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert 5096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert public WebCorpus(Context context, Config config, SearchSettings settings, Executor executor, 51f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert Source webSearchSource, Source browserSource) { 5296c7058210699c82445169048b7c0fdfb16f59eeBjorn Bringert super(context, config, executor, webSearchSource, browserSource); 53848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (DBG) { 54848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani Log.d(TAG, "init webSource=" + webSearchSource + "; browser source = " + browserSource); 55848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 5696fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert mSettings = settings; 57fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mWebSearchSource = webSearchSource; 5813ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert mBrowserSource = browserSource; 59fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 60fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 6196fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert protected SearchSettings getSettings() { 6296fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert return mSettings; 6396fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert } 6496fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert 65848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani public void setWebSource(Source web) { 66848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (DBG) Log.d(TAG, "setWebSource(" + web + ")"); 67848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani mWebSearchSource = web; 68848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 69848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 70fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public CharSequence getLabel() { 71fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getContext().getText(R.string.corpus_label_web); 72fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 73fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 745691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert public CharSequence getHint() { 755691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert // The web corpus uses a drawable hint instead 765691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert return null; 775691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 785691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert 79c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert private boolean isUrl(String query) { 80c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert return Patterns.WEB_URL.matcher(query).matches(); 81fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 82fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 83c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert public Intent createSearchIntent(String query, Bundle appData) { 840be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert if (isUrl(query)) { 850be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert return createBrowseIntent(query); 860be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert } else if (mWebSearchSource != null){ 870be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert return mWebSearchSource.createSearchIntent(query, appData); 880be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert } else { 890be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert return null; 90fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 91fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 92fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 930be2eb803011b1ef8c2c8277c330fe5ad975316bBjorn Bringert private Intent createBrowseIntent(String query) { 94fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Intent intent = new Intent(Intent.ACTION_VIEW); 95fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert intent.addCategory(Intent.CATEGORY_BROWSABLE); 96fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 97fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 98c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert String url = URLUtil.guessUrl(query); 99fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert intent.setData(Uri.parse(url)); 100fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return intent; 101fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 102fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 103fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public Intent createVoiceSearchIntent(Bundle appData) { 104848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani // TODO in 2-pane mode, mWebSearchSource may be NULL 105848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani // this functionality should be moved elsewhere. 10649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert if (mWebSearchSource != null){ 10749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return mWebSearchSource.createVoiceSearchIntent(appData); 10849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } else { 10949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return null; 11049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 111fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 112fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 1132353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert private int getCorpusIconResource() { 1142353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert return R.drawable.corpus_icon_web; 1152353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert } 1162353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert 117fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public Drawable getCorpusIcon() { 1182353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert return getContext().getResources().getDrawable(getCorpusIconResource()); 119fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 120fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 121fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public Uri getCorpusIconUri() { 1222353e9c002c45c0adc8a979a49ff317cae5838b8Bjorn Bringert return Util.getResourceUri(getContext(), getCorpusIconResource()); 123fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 124fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 125fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public String getName() { 126fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return WEB_CORPUS_NAME; 127fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 128fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 1293cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood @Override 130fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public int getQueryThreshold() { 131fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return 0; 132fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 133fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 1343cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood @Override 135fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean queryAfterZeroResults() { 136fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return true; 137fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 138fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 1393cb8178193a41f6c74ee396c318385a50dd624e1Mathew Inwood @Override 140fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean voiceSearchEnabled() { 141fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return true; 142fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 143fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 144fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean isWebCorpus() { 145fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return true; 146fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 147fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 148fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public CharSequence getSettingsDescription() { 149fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getContext().getText(R.string.corpus_description_web); 150fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 151fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 152f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert @Override 153cd1e3ba5f7c3f5242345ff6f674281e3d6366e24Mathew Inwood protected List<Source> getSourcesToQuery(String query, boolean onlyCorpus) { 154dbda78401b4b25ac1da77b2db75f0657f2705b1dBryan Mawhinney ArrayList<Source> sourcesToQuery = new ArrayList<Source>(2); 15534955d44dddabfc672a26263363190f971c337a8Mathew Inwood if (mWebSearchSource != null) sourcesToQuery.add(mWebSearchSource); 156dbda78401b4b25ac1da77b2db75f0657f2705b1dBryan Mawhinney if (mBrowserSource != null && query.length() > 0) { 157dbda78401b4b25ac1da77b2db75f0657f2705b1dBryan Mawhinney sourcesToQuery.add(mBrowserSource); 15813ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert } 159848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (DBG) Log.d(TAG, "getSourcesToQuery sourcesToQuery=" + sourcesToQuery); 160dbda78401b4b25ac1da77b2db75f0657f2705b1dBryan Mawhinney return sourcesToQuery; 16113ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert } 16213ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert 16313ace1d0d0fa7e4c7aa7898a828763d8880db463Bjorn Bringert @Override 164f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert protected Result createResult(String query, ArrayList<SourceResult> results, int latency) { 165f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert return new WebResult(query, results, latency); 166fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 167fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 168f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert protected class WebResult extends Result { 169fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 170f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert public WebResult(String query, ArrayList<SourceResult> results, int latency) { 171f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert super(query, results, latency); 172f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert } 173fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 174f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert @Override 175f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert public void fill() { 176f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert SourceResult webSearchResult = null; 177f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert SourceResult browserResult = null; 178f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert for (SourceResult result : getResults()) { 179f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert if (result.getSource().equals(mWebSearchSource)) { 180f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert webSearchResult = result; 181f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert } else { 182f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert browserResult = result; 183f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert } 184fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 185f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert if (browserResult != null && browserResult.getCount() > 0) { 186f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert add(new SuggestionPosition(browserResult, 0)); 187f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert } 188f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert if (webSearchResult != null) { 189f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert int count = webSearchResult.getCount(); 190fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert for (int i = 0; i < count; i++) { 191f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert add(new SuggestionPosition(webSearchResult, i)); 192fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 193fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 194fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 195fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 196fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 197fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert} 198