Home | History | Annotate | Download | only in quicksearchbox
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.quicksearchbox;
     18 
     19 
     20 import com.android.quicksearchbox.util.Util;
     21 
     22 import android.app.SearchManager;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.graphics.drawable.Drawable;
     26 import android.net.Uri;
     27 import android.os.Bundle;
     28 import android.speech.RecognizerIntent;
     29 import android.util.Patterns;
     30 import android.webkit.URLUtil;
     31 
     32 import java.util.ArrayList;
     33 import java.util.List;
     34 import java.util.concurrent.Executor;
     35 
     36 /**
     37  * The web search source.
     38  */
     39 public class WebCorpus extends MultiSourceCorpus {
     40 
     41     private static final String WEB_CORPUS_NAME = "web";
     42 
     43     private final Source mWebSearchSource;
     44 
     45     private final Source mBrowserSource;
     46 
     47     public WebCorpus(Context context, Executor executor,
     48             Source webSearchSource, Source browserSource) {
     49         super(context, executor, webSearchSource, browserSource);
     50         mWebSearchSource = webSearchSource;
     51         mBrowserSource = browserSource;
     52     }
     53 
     54     public CharSequence getLabel() {
     55         return getContext().getText(R.string.corpus_label_web);
     56     }
     57 
     58     public CharSequence getHint() {
     59         // The web corpus uses a drawable hint instead
     60         return null;
     61     }
     62 
     63     private boolean isUrl(String query) {
     64        return Patterns.WEB_URL.matcher(query).matches();
     65     }
     66 
     67     public Intent createSearchIntent(String query, Bundle appData) {
     68         return isUrl(query)? createBrowseIntent(query) : createWebSearchIntent(query, appData);
     69     }
     70 
     71     private static Intent createWebSearchIntent(String query, Bundle appData) {
     72         Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
     73         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     74         // We need CLEAR_TOP to avoid reusing an old task that has other activities
     75         // on top of the one we want.
     76         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
     77         intent.putExtra(SearchManager.USER_QUERY, query);
     78         intent.putExtra(SearchManager.QUERY, query);
     79         if (appData != null) {
     80             intent.putExtra(SearchManager.APP_DATA, appData);
     81         }
     82         // TODO: Include something like this, to let the web search activity
     83         // know how this query was started.
     84         //intent.putExtra(SearchManager.SEARCH_MODE, SearchManager.MODE_GLOBAL_SEARCH_TYPED_QUERY);
     85         return intent;
     86     }
     87 
     88     private static Intent createBrowseIntent(String query) {
     89         Intent intent = new Intent(Intent.ACTION_VIEW);
     90         intent.addCategory(Intent.CATEGORY_BROWSABLE);
     91         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     92         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
     93         String url = URLUtil.guessUrl(query);
     94         intent.setData(Uri.parse(url));
     95         return intent;
     96     }
     97 
     98     public SuggestionData createSearchShortcut(String query) {
     99         SuggestionData shortcut = new SuggestionData(mWebSearchSource);
    100         if (isUrl(query)) {
    101             shortcut.setIntentAction(Intent.ACTION_VIEW);
    102             shortcut.setIcon1(String.valueOf(R.drawable.globe));
    103             shortcut.setText1(query);
    104             // Set query so that trackball selection works
    105             shortcut.setSuggestionQuery(query);
    106             shortcut.setIntentData(URLUtil.guessUrl(query));
    107         } else {
    108             shortcut.setIntentAction(Intent.ACTION_WEB_SEARCH);
    109             shortcut.setIcon1(String.valueOf(R.drawable.magnifying_glass));
    110             shortcut.setText1(query);
    111             shortcut.setSuggestionQuery(query);
    112         }
    113         return shortcut;
    114     }
    115 
    116     public Intent createVoiceSearchIntent(Bundle appData) {
    117         return createVoiceWebSearchIntent(appData);
    118     }
    119 
    120     public static Intent createVoiceWebSearchIntent(Bundle appData) {
    121         Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
    122         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    123         intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
    124                 RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    125         if (appData != null) {
    126             intent.putExtra(SearchManager.APP_DATA, appData);
    127         }
    128         return intent;
    129     }
    130 
    131     private int getCorpusIconResource() {
    132         return R.drawable.corpus_icon_web;
    133     }
    134 
    135     public Drawable getCorpusIcon() {
    136         return getContext().getResources().getDrawable(getCorpusIconResource());
    137     }
    138 
    139     public Uri getCorpusIconUri() {
    140         return Util.getResourceUri(getContext(), getCorpusIconResource());
    141     }
    142 
    143     public String getName() {
    144         return WEB_CORPUS_NAME;
    145     }
    146 
    147     public int getQueryThreshold() {
    148         return 0;
    149     }
    150 
    151     public boolean queryAfterZeroResults() {
    152         return true;
    153     }
    154 
    155     public boolean voiceSearchEnabled() {
    156         return true;
    157     }
    158 
    159     public boolean isWebCorpus() {
    160         return true;
    161     }
    162 
    163     public CharSequence getSettingsDescription() {
    164         return getContext().getText(R.string.corpus_description_web);
    165     }
    166 
    167     @Override
    168     protected List<Source> getSourcesToQuery(String query) {
    169         ArrayList<Source> sourcesToQuery = new ArrayList<Source>(2);
    170         if (mWebSearchSource != null
    171                 && SearchSettings.getShowWebSuggestions(getContext())) {
    172             sourcesToQuery.add(mWebSearchSource);
    173         }
    174         if (mBrowserSource != null && query.length() > 0) {
    175             sourcesToQuery.add(mBrowserSource);
    176         }
    177         return sourcesToQuery;
    178     }
    179 
    180     @Override
    181     protected Result createResult(String query, ArrayList<SourceResult> results, int latency) {
    182         return new WebResult(query, results, latency);
    183     }
    184 
    185     protected class WebResult extends Result {
    186 
    187         public WebResult(String query, ArrayList<SourceResult> results, int latency) {
    188             super(query, results, latency);
    189         }
    190 
    191         @Override
    192         public void fill() {
    193             SourceResult webSearchResult = null;
    194             SourceResult browserResult = null;
    195             for (SourceResult result : getResults()) {
    196                 if (result.getSource().equals(mWebSearchSource)) {
    197                     webSearchResult = result;
    198                 } else {
    199                     browserResult = result;
    200                 }
    201             }
    202             if (browserResult != null && browserResult.getCount() > 0) {
    203                 add(new SuggestionPosition(browserResult, 0));
    204             }
    205             if (webSearchResult != null) {
    206                 int count = webSearchResult.getCount();
    207                 for (int i = 0; i < count; i++) {
    208                     add(new SuggestionPosition(webSearchResult, i));
    209                 }
    210             }
    211         }
    212 
    213     }
    214 }
    215