WebCorpus.java revision 13ace1d0d0fa7e4c7aa7898a828763d8880db463
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.NamedTaskExecutor;
21
22import android.app.SearchManager;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.Intent;
26import android.graphics.drawable.Drawable;
27import android.net.Uri;
28import android.os.Bundle;
29import android.speech.RecognizerIntent;
30import android.util.Patterns;
31import android.webkit.URLUtil;
32
33import java.util.ArrayList;
34import java.util.Collections;
35import java.util.List;
36
37/**
38 * The web search source.
39 */
40public class WebCorpus extends MultiSourceCorpus {
41
42    private static final String WEB_CORPUS_NAME = "web";
43
44    private final Source mWebSearchSource;
45
46    private final Source mBrowserSource;
47
48    public WebCorpus(Context context, NamedTaskExecutor executor,
49            Source webSearchSource, Source browserSource) {
50        super(context, executor, webSearchSource, browserSource);
51        mWebSearchSource = webSearchSource;
52        mBrowserSource = browserSource;
53    }
54
55    public CharSequence getLabel() {
56        return getContext().getText(R.string.corpus_label_web);
57    }
58
59    public CharSequence getHint() {
60        // The web corpus uses a drawable hint instead
61        return null;
62    }
63
64    private boolean isUrl(String query) {
65       return Patterns.WEB_URL.matcher(query).matches();
66    }
67
68    public Intent createSearchIntent(String query, Bundle appData) {
69        return isUrl(query)? createBrowseIntent(query) : createWebSearchIntent(query, appData);
70    }
71
72    private static Intent createWebSearchIntent(String query, Bundle appData) {
73        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
74        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
75        // We need CLEAR_TOP to avoid reusing an old task that has other activities
76        // on top of the one we want.
77        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
78        intent.putExtra(SearchManager.USER_QUERY, query);
79        intent.putExtra(SearchManager.QUERY, query);
80        if (appData != null) {
81            intent.putExtra(SearchManager.APP_DATA, appData);
82        }
83        // TODO: Include something like this, to let the web search activity
84        // know how this query was started.
85        //intent.putExtra(SearchManager.SEARCH_MODE, SearchManager.MODE_GLOBAL_SEARCH_TYPED_QUERY);
86        return intent;
87    }
88
89    private static Intent createBrowseIntent(String query) {
90        Intent intent = new Intent(Intent.ACTION_VIEW);
91        intent.addCategory(Intent.CATEGORY_BROWSABLE);
92        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
93        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
94        String url = URLUtil.guessUrl(query);
95        intent.setData(Uri.parse(url));
96        return intent;
97    }
98
99    public SuggestionData createSearchShortcut(String query) {
100        SuggestionData shortcut = new SuggestionData(mWebSearchSource);
101        if (isUrl(query)) {
102            shortcut.setIntentAction(Intent.ACTION_VIEW);
103            shortcut.setIcon1(String.valueOf(R.drawable.globe));
104            shortcut.setText1(query);
105            // Set query so that trackball selection works
106            shortcut.setSuggestionQuery(query);
107            shortcut.setIntentData(URLUtil.guessUrl(query));
108        } else {
109            shortcut.setIntentAction(Intent.ACTION_WEB_SEARCH);
110            shortcut.setIcon1(String.valueOf(R.drawable.magnifying_glass));
111            shortcut.setText1(query);
112            shortcut.setSuggestionQuery(query);
113        }
114        return shortcut;
115    }
116
117    public Intent createVoiceSearchIntent(Bundle appData) {
118        return createVoiceWebSearchIntent(appData);
119    }
120
121    public static Intent createVoiceWebSearchIntent(Bundle appData) {
122        Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
123        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
124        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
125                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
126        if (appData != null) {
127            intent.putExtra(SearchManager.APP_DATA, appData);
128        }
129        return intent;
130    }
131
132    public Drawable getCorpusIcon() {
133        return getContext().getResources().getDrawable(R.drawable.corpus_icon_web);
134    }
135
136    public Uri getCorpusIconUri() {
137        int resourceId = R.drawable.corpus_icon_web;
138        return new Uri.Builder()
139                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
140                .authority(getContext().getPackageName())
141                .appendEncodedPath(String.valueOf(resourceId))
142                .build();
143    }
144
145    public String getName() {
146        return WEB_CORPUS_NAME;
147    }
148
149    public int getQueryThreshold() {
150        return 0;
151    }
152
153    public boolean queryAfterZeroResults() {
154        return true;
155    }
156
157    public boolean voiceSearchEnabled() {
158        return true;
159    }
160
161    public boolean isWebCorpus() {
162        return true;
163    }
164
165    public CharSequence getSettingsDescription() {
166        return getContext().getText(R.string.corpus_description_web);
167    }
168
169    @Override
170    protected List<Source> getSourcesToQuery(String query) {
171        if (SearchSettings.getShowWebSuggestions(getContext())) {
172            return super.getSourcesToQuery(query);
173        } else if (mBrowserSource != null) {
174            return Collections.singletonList(mBrowserSource);
175        } else {
176            return Collections.emptyList();
177        }
178    }
179
180    @Override
181    protected Result createResult(String query, ArrayList<SourceResult> results) {
182        return new WebResult(query, results);
183    }
184
185    protected class WebResult extends Result {
186
187        public WebResult(String query, ArrayList<SourceResult> results) {
188            super(query, results);
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