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
186747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringertimport android.app.PendingIntent;
19d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.app.SearchManager;
20d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.app.SearchableInfo;
21d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.ActivityNotFoundException;
22d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.ComponentName;
23d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Context;
24d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.Intent;
25d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.pm.ActivityInfo;
26d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.content.pm.PackageManager;
27d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.database.Cursor;
28d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.os.Bundle;
29d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.provider.Browser;
30d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.text.TextUtils;
31d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertimport android.util.Log;
32d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
33d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringertpublic class DefaultSearchEngine implements SearchEngine {
34d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
35d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private static final String TAG = "DefaultSearchEngine";
36d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
37d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private final SearchableInfo mSearchable;
38d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
39d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private final CharSequence mLabel;
40d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
41d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private DefaultSearchEngine(Context context, SearchableInfo searchable) {
42d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        mSearchable = searchable;
43d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        mLabel = loadLabel(context, mSearchable.getSearchActivity());
44d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
45d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
46d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public static DefaultSearchEngine create(Context context) {
47d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchManager searchManager =
48d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
49d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        ComponentName name = searchManager.getWebSearchActivity();
50d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if (name == null) return null;
51d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchableInfo searchable = searchManager.getSearchableInfo(name);
52d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if (searchable == null) return null;
53d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return new DefaultSearchEngine(context, searchable);
54d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
55d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
56d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    private CharSequence loadLabel(Context context, ComponentName activityName) {
57d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        PackageManager pm = context.getPackageManager();
58d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        try {
59d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            ActivityInfo ai = pm.getActivityInfo(activityName, 0);
60d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return ai.loadLabel(pm);
61d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } catch (PackageManager.NameNotFoundException ex) {
62d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Log.e(TAG, "Web search activity not found: " + activityName);
63d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return null;
64d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
65d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
66d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
67d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public String getName() {
68d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        String packageName = mSearchable.getSearchActivity().getPackageName();
69d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        // Use "google" as name to avoid showing Google twice (app + OpenSearch)
70d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        if ("com.google.android.googlequicksearchbox".equals(packageName)) {
71430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III            return SearchEngine.GOOGLE;
72d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } else if ("com.android.quicksearchbox".equals(packageName)) {
73430057dad085f3c3dbc386f127b1f5a10a9851daLeon Scroggins III            return SearchEngine.GOOGLE;
74d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } else {
75d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            return packageName;
76d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
77d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
78d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
79d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public CharSequence getLabel() {
80d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return mLabel;
81d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
82d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
83d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public void startSearch(Context context, String query, Bundle appData, String extraData) {
84d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        try {
85d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
86785ad9a5258db19e8c98eb7969aff453af944565Bjorn Bringert            intent.setComponent(mSearchable.getSearchActivity());
87d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.addCategory(Intent.CATEGORY_DEFAULT);
88d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.putExtra(SearchManager.QUERY, query);
89d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            if (appData != null) {
90d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                intent.putExtra(SearchManager.APP_DATA, appData);
91d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            }
92d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            if (extraData != null) {
93d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
94d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            }
95d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
966747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert            Intent viewIntent = new Intent(Intent.ACTION_VIEW);
976747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert            viewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
986747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert            viewIntent.setPackage(context.getPackageName());
996747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert            PendingIntent pending = PendingIntent.getActivity(context, 0, viewIntent,
1006747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert                    PendingIntent.FLAG_ONE_SHOT);
1016747e0a22235ee1652e81f40e62828268f30c1cbBjorn Bringert            intent.putExtra(SearchManager.EXTRA_WEB_SEARCH_PENDINGINTENT, pending);
102d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            context.startActivity(intent);
103d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        } catch (ActivityNotFoundException ex) {
104d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert            Log.e(TAG, "Web search activity not found: " + mSearchable.getSearchActivity());
105d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        }
106d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
107d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
108d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public Cursor getSuggestions(Context context, String query) {
109d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        SearchManager searchManager =
110d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
111d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return searchManager.getSuggestions(mSearchable, query);
112d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
113d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
114d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public boolean supportsSuggestions() {
115d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return !TextUtils.isEmpty(mSearchable.getSuggestAuthority());
116d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
117d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
118d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public void close() {
119d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
120d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
121d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    @Override
122d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    public String toString() {
123d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert        return "ActivitySearchEngine{" + mSearchable + "}";
124d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert    }
125d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert
1265119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    @Override
1275119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    public boolean wantsEmptyQuery() {
1285119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath        return false;
1295119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath    }
1305119edd5744cfc6d3a8ed480a8853586c737bed4Narayan Kamath
131d26706538834e0ed58bf28f08d9a2885c0e7efcbBjorn Bringert}
132