1d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert/*
2d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Copyright (C) 2010 The Android Open Source Project
3d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert *
4d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
5d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * you may not use this file except in compliance with the License.
6d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * You may obtain a copy of the License at
7d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert *
8d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
9d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert *
10d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * Unless required by applicable law or agreed to in writing, software
11d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
12d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * See the License for the specific language governing permissions and
14d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert * limitations under the License.
15d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert */
16d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertpackage com.android.browser.search;
17d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
18d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.app.SearchManager;
19d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.app.SearchableInfo;
20d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.ActivityNotFoundException;
21d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.ComponentName;
22d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Context;
23d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Intent;
24d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.pm.ActivityInfo;
25d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.pm.PackageManager;
26d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.database.Cursor;
27d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.os.Bundle;
28d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.provider.Browser;
29d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.text.TextUtils;
30d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.util.Log;
31d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
32d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertpublic class DefaultSearchEngine implements SearchEngine {
33d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
34d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private static final String TAG = "DefaultSearchEngine";
35d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
36d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private final SearchableInfo mSearchable;
37d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
38d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private final CharSequence mLabel;
39d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
40d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private DefaultSearchEngine(Context context, SearchableInfo searchable) {
41d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        mSearchable = searchable;
42d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        mLabel = loadLabel(context, mSearchable.getSearchActivity());
43d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
44d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
45d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public static DefaultSearchEngine create(Context context) {
46d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchManager searchManager =
47d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
48d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        ComponentName name = searchManager.getWebSearchActivity();
49d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if (name == null) return null;
50d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchableInfo searchable = searchManager.getSearchableInfo(name);
51d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if (searchable == null) return null;
52d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return new DefaultSearchEngine(context, searchable);
53d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
54d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
55d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private CharSequence loadLabel(Context context, ComponentName activityName) {
56d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        PackageManager pm = context.getPackageManager();
57d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        try {
58d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            ActivityInfo ai = pm.getActivityInfo(activityName, 0);
59d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return ai.loadLabel(pm);
60d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } catch (PackageManager.NameNotFoundException ex) {
61d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Log.e(TAG, "Web search activity not found: " + activityName);
62d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return null;
63d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
64d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
65d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
66d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public String getName() {
67d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        String packageName = mSearchable.getSearchActivity().getPackageName();
68d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        // Use "google" as name to avoid showing Google twice (app + OpenSearch)
69d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if ("com.google.android.googlequicksearchbox".equals(packageName)) {
70430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III            return SearchEngine.GOOGLE;
71d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } else if ("com.android.quicksearchbox".equals(packageName)) {
72430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III            return SearchEngine.GOOGLE;
73d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } else {
74d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return packageName;
75d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
76d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
77d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
78d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public CharSequence getLabel() {
79d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return mLabel;
80d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
81d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
82d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public void startSearch(Context context, String query, Bundle appData, String extraData) {
83d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        try {
84d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
85785ad9a5258db19e8c98eb7969aff453af944565Bjorn Bringert            intent.setComponent(mSearchable.getSearchActivity());
86d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.addCategory(Intent.CATEGORY_DEFAULT);
87d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.putExtra(SearchManager.QUERY, query);
88d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            if (appData != null) {
89d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                intent.putExtra(SearchManager.APP_DATA, appData);
90d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            }
91d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            if (extraData != null) {
92d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
93d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            }
94d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
95d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            context.startActivity(intent);
96d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } catch (ActivityNotFoundException ex) {
97d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Log.e(TAG, "Web search activity not found: " + mSearchable.getSearchActivity());
98d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
99d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
100d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
101d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public Cursor getSuggestions(Context context, String query) {
102d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchManager searchManager =
103d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
104d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return searchManager.getSuggestions(mSearchable, query);
105d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
106d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
107d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public boolean supportsSuggestions() {
108d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return !TextUtils.isEmpty(mSearchable.getSuggestAuthority());
109d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
110d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
111d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public void close() {
112d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
113d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
114430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III    public boolean supportsVoiceSearch() {
115430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III        return getName().equals(SearchEngine.GOOGLE);
116430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III    }
117430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III
118d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    @Override
119d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public String toString() {
120d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return "ActivitySearchEngine{" + mSearchable + "}";
121d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
122d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
123d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert}
124