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