WebCorpus.java revision 72f9b08ce84d0e13daf2d1c112d4e6d1d3ada045
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 android.app.SearchManager;
21import android.content.ContentResolver;
22import android.content.Context;
23import android.content.Intent;
24import android.graphics.drawable.Drawable;
25import android.net.Uri;
26import android.os.Bundle;
27import android.speech.RecognizerIntent;
28import android.util.Patterns;
29import android.webkit.URLUtil;
30
31import java.util.ArrayList;
32import java.util.Collections;
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    public Drawable getCorpusIcon() {
132        return getContext().getResources().getDrawable(R.drawable.corpus_icon_web);
133    }
134
135    public Uri getCorpusIconUri() {
136        int resourceId = R.drawable.corpus_icon_web;
137        return new Uri.Builder()
138                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
139                .authority(getContext().getPackageName())
140                .appendEncodedPath(String.valueOf(resourceId))
141                .build();
142    }
143
144    public String getName() {
145        return WEB_CORPUS_NAME;
146    }
147
148    public int getQueryThreshold() {
149        return 0;
150    }
151
152    public boolean queryAfterZeroResults() {
153        return true;
154    }
155
156    public boolean voiceSearchEnabled() {
157        return true;
158    }
159
160    public boolean isWebCorpus() {
161        return true;
162    }
163
164    public CharSequence getSettingsDescription() {
165        return getContext().getText(R.string.corpus_description_web);
166    }
167
168    @Override
169    protected List<Source> getSourcesToQuery(String query) {
170        if (SearchSettings.getShowWebSuggestions(getContext())) {
171            return super.getSourcesToQuery(query);
172        } else if (mBrowserSource != null) {
173            return Collections.singletonList(mBrowserSource);
174        } else {
175            return Collections.emptyList();
176        }
177    }
178
179    @Override
180    protected Result createResult(String query, ArrayList<SourceResult> results) {
181        return new WebResult(query, results);
182    }
183
184    protected class WebResult extends Result {
185
186        public WebResult(String query, ArrayList<SourceResult> results) {
187            super(query, results);
188        }
189
190        @Override
191        public void fill() {
192            SourceResult webSearchResult = null;
193            SourceResult browserResult = null;
194            for (SourceResult result : getResults()) {
195                if (result.getSource().equals(mWebSearchSource)) {
196                    webSearchResult = result;
197                } else {
198                    browserResult = result;
199                }
200            }
201            if (browserResult != null && browserResult.getCount() > 0) {
202                add(new SuggestionPosition(browserResult, 0));
203            }
204            if (webSearchResult != null) {
205                int count = webSearchResult.getCount();
206                for (int i = 0; i < count; i++) {
207                    add(new SuggestionPosition(webSearchResult, i));
208                }
209            }
210        }
211
212    }
213}
214