WebCorpus.java revision b5fc08b7f16a32d3865f44b7f26d8aaa5304a2ad
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
17package com.android.quicksearchbox;
18
19
20import com.android.quicksearchbox.util.Util;
21
22import android.app.SearchManager;
23import android.content.Context;
24import android.content.Intent;
25import android.graphics.drawable.Drawable;
26import android.net.Uri;
27import android.os.Bundle;
28import android.speech.RecognizerIntent;
29import android.util.Patterns;
30import android.webkit.URLUtil;
31
32import java.util.ArrayList;
33import java.util.List;
34import java.util.concurrent.Executor;
35
36/**
37 * The web search source.
38 */
39public 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