SearchSettings.java revision 8d9d845323514c34bb07d6eb91146a975324fced
1/*
2 * Copyright (C) 2009 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
19import android.app.AlertDialog;
20import android.app.Dialog;
21import android.app.SearchManager;
22import android.content.DialogInterface;
23import android.content.Intent;
24import android.content.pm.PackageManager;
25import android.content.pm.ResolveInfo;
26import android.os.Bundle;
27import android.preference.CheckBoxPreference;
28import android.preference.Preference;
29import android.preference.PreferenceActivity;
30import android.preference.PreferenceGroup;
31import android.preference.PreferenceScreen;
32import android.preference.Preference.OnPreferenceChangeListener;
33import android.preference.Preference.OnPreferenceClickListener;
34import android.util.Log;
35
36import java.util.List;
37
38/**
39 * Activity for setting global search preferences. Changes to search preferences trigger a broadcast
40 * intent that causes all SuggestionSources objects to be updated.
41 */
42public class SearchSettings extends PreferenceActivity
43        implements OnPreferenceClickListener, OnPreferenceChangeListener {
44
45    private static final boolean DBG = false;
46    private static final String TAG = "SearchSettings";
47
48    // Only used to find the preferences after inflating
49    private static final String CLEAR_SHORTCUTS_PREF = "clear_shortcuts";
50    private static final String SEARCH_ENGINE_SETTINGS_PREF = "search_engine_settings";
51    private static final String SEARCH_SOURCES_PREF = "search_sources";
52
53    private SourceLookup mSources;
54    private ShortcutRepository mShortcuts;
55
56    // References to the top-level preference objects
57    private Preference mClearShortcutsPreference;
58    private PreferenceScreen mSearchEngineSettingsPreference;
59    private PreferenceGroup mSourcePreferences;
60
61    // Dialog ids
62    private static final int CLEAR_SHORTCUTS_CONFIRM_DIALOG = 0;
63
64    @Override
65    protected void onCreate(Bundle savedInstanceState) {
66        super.onCreate(savedInstanceState);
67
68        mSources = getSources();
69        mShortcuts = getQSBApplication().getShortcutRepository();
70        getPreferenceManager().setSharedPreferencesName(Sources.PREFERENCES_NAME);
71
72        addPreferencesFromResource(R.xml.preferences);
73
74        PreferenceScreen preferenceScreen = getPreferenceScreen();
75        mClearShortcutsPreference = preferenceScreen.findPreference(CLEAR_SHORTCUTS_PREF);
76        mSearchEngineSettingsPreference = (PreferenceScreen) preferenceScreen.findPreference(
77                SEARCH_ENGINE_SETTINGS_PREF);
78        mSourcePreferences = (PreferenceGroup) getPreferenceScreen().findPreference(
79                SEARCH_SOURCES_PREF);
80
81        mClearShortcutsPreference.setOnPreferenceClickListener(this);
82
83        updateClearShortcutsPreference();
84        populateSourcePreference();
85        populateSearchEnginePreference();
86    }
87
88    @Override
89    protected void onDestroy() {
90        mShortcuts.close();
91        super.onDestroy();
92    }
93
94    private QsbApplication getQSBApplication() {
95        return (QsbApplication) getApplication();
96    }
97
98    private Config getConfig() {
99        return getQSBApplication().getConfig();
100    }
101
102    private SourceLookup getSources() {
103        return getQSBApplication().getSources();
104    }
105
106    /**
107     * Enables/disables the "Clear search shortcuts" preference depending
108     * on whether there is any search history.
109     */
110    private void updateClearShortcutsPreference() {
111        boolean hasHistory = mShortcuts.hasHistory();
112        if (DBG) Log.d(TAG, "hasHistory()=" + hasHistory);
113        mClearShortcutsPreference.setEnabled(hasHistory);
114    }
115
116    /**
117     * Populates the preference item for the web search engine, which links to further
118     * search settings.
119     */
120    private void populateSearchEnginePreference() {
121        Intent intent = new Intent(SearchManager.INTENT_ACTION_WEB_SEARCH_SETTINGS);
122        intent.setPackage(getPackageName());
123
124        CharSequence webSearchSettingsLabel = getActivityLabel(intent);
125        mSearchEngineSettingsPreference.setTitle(webSearchSettingsLabel);
126        mSearchEngineSettingsPreference.setIntent(intent);
127    }
128
129    private CharSequence getActivityLabel(Intent intent) {
130        PackageManager pm = getPackageManager();
131        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
132        if (resolveInfos.size() == 0) {
133            Log.e(TAG, "No web search settings activity");
134            return null;
135        }
136        if (resolveInfos.size() > 1) {
137            Log.e(TAG, "More than one web search settings activity");
138            return null;
139        }
140        return resolveInfos.get(0).activityInfo.loadLabel(pm);
141    }
142
143    /**
144     * Fills the suggestion source list.
145     */
146    private void populateSourcePreference() {
147        for (Source source : mSources.getSources()) {
148            Preference pref = createSourcePreference(source);
149            if (pref != null) {
150                if (DBG) Log.d(TAG, "Adding search source: " + source);
151                mSourcePreferences.addPreference(pref);
152            }
153        }
154    }
155
156    /**
157     * Adds a suggestion source to the list of suggestion source checkbox preferences.
158     */
159    private Preference createSourcePreference(Source source) {
160        CheckBoxPreference sourcePref = new CheckBoxPreference(this);
161        sourcePref.setKey(Sources.getSourceEnabledPreference(source));
162        sourcePref.setDefaultValue(mSources.isTrustedSource(source));
163        sourcePref.setOnPreferenceChangeListener(this);
164        CharSequence label = source.getLabel();
165        sourcePref.setTitle(label);
166        CharSequence description = source.getSettingsDescription();
167        sourcePref.setSummaryOn(description);
168        sourcePref.setSummaryOff(description);
169        return sourcePref;
170    }
171
172    /**
173     * Handles clicks on the "Clear search shortcuts" preference.
174     */
175    public synchronized boolean onPreferenceClick(Preference preference) {
176        if (preference == mClearShortcutsPreference) {
177            showDialog(CLEAR_SHORTCUTS_CONFIRM_DIALOG);
178            return true;
179        }
180        return false;
181    }
182
183    @Override
184    protected Dialog onCreateDialog(int id) {
185        switch (id) {
186            case CLEAR_SHORTCUTS_CONFIRM_DIALOG:
187                return new AlertDialog.Builder(this)
188                        .setTitle(R.string.clear_shortcuts)
189                        .setMessage(R.string.clear_shortcuts_prompt)
190                        .setPositiveButton(R.string.agree, new DialogInterface.OnClickListener() {
191                            public void onClick(DialogInterface dialog, int whichButton) {
192                                if (DBG) Log.d(TAG, "Clearing history...");
193                                mShortcuts.clearHistory();
194                                updateClearShortcutsPreference();
195                            }
196                        })
197                        .setNegativeButton(R.string.disagree, null).create();
198            default:
199                Log.e(TAG, "unknown dialog" + id);
200                return null;
201        }
202    }
203
204    /**
205     * Informs our listeners (SuggestionSources objects) about the updated settings data.
206     */
207    private void broadcastSettingsChanged() {
208        // We use a message broadcast since the listeners could be in multiple processes.
209        Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS_CHANGED);
210        Log.i(TAG, "Broadcasting: " + intent);
211        sendBroadcast(intent);
212    }
213
214    public synchronized boolean onPreferenceChange(Preference preference, Object newValue) {
215        broadcastSettingsChanged();
216        return true;
217    }
218
219}
220