SearchSettingsImpl.java revision 73a375928e0b8f0b2bfa09e4b252cfcbdad4ef84
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.SearchManager;
20import android.content.Context;
21import android.content.Intent;
22import android.content.SharedPreferences;
23import android.util.Log;
24import android.view.Menu;
25import android.view.MenuInflater;
26import android.view.MenuItem;
27
28/**
29 * Manages user settings.
30 */
31public class SearchSettingsImpl implements SearchSettings {
32
33    private static final boolean DBG = false;
34    private static final String TAG = "QSB.SearchSettingsImpl";
35
36    // Name of the preferences file used to store search preference
37    public static final String PREFERENCES_NAME = "SearchSettings";
38
39    // Intent action that opens the "Searchable Items" preference
40    private static final String ACTION_SEARCHABLE_ITEMS =
41            "com.android.quicksearchbox.action.SEARCHABLE_ITEMS";
42
43    /**
44     * Preference key used for storing the index of the next voice search hint to show.
45     */
46    private static final String NEXT_VOICE_SEARCH_HINT_INDEX_PREF = "next_voice_search_hint";
47
48    /**
49     * Preference key used to store the time at which the first voice search hint was displayed.
50     */
51    private static final String FIRST_VOICE_HINT_DISPLAY_TIME = "first_voice_search_hint_time";
52
53    /**
54     * Preference key for the version of voice search we last got hints from.
55     */
56    private static final String LAST_SEEN_VOICE_SEARCH_VERSION = "voice_search_version";
57
58    /**
59     * Prefix of per-corpus enable preference
60     */
61    private static final String CORPUS_ENABLED_PREF_PREFIX = "enable_corpus_";
62
63    private final Context mContext;
64
65    private final Config mConfig;
66
67    public SearchSettingsImpl(Context context, Config config) {
68        mContext = context;
69        mConfig = config;
70    }
71
72    protected Context getContext() {
73        return mContext;
74    }
75
76    protected Config getConfig() {
77        return mConfig;
78    }
79
80    public void upgradeSettingsIfNeeded() {
81    }
82
83    public Intent getSearchableItemsIntent() {
84        Intent intent = new Intent(ACTION_SEARCHABLE_ITEMS);
85        intent.setPackage(getContext().getPackageName());
86        return intent;
87    }
88
89    /**
90     * Gets the preference key of the preference for whether the given corpus
91     * is enabled. The preference is stored in the {@link #PREFERENCES_NAME}
92     * preferences file.
93     */
94    public static String getCorpusEnabledPreference(Corpus corpus) {
95        return CORPUS_ENABLED_PREF_PREFIX + corpus.getName();
96    }
97
98    public boolean isCorpusEnabled(Corpus corpus) {
99        boolean defaultEnabled = corpus.isCorpusDefaultEnabled();
100        String sourceEnabledPref = getCorpusEnabledPreference(corpus);
101        return getSearchPreferences().getBoolean(sourceEnabledPref, defaultEnabled);
102    }
103
104    protected SharedPreferences getSearchPreferences() {
105        return getContext().getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
106    }
107
108    /**
109     * Informs our listeners about the updated settings data.
110     */
111    public void broadcastSettingsChanged() {
112        // We use a message broadcast since the listeners could be in multiple processes.
113        Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS_CHANGED);
114        Log.i(TAG, "Broadcasting: " + intent);
115        getContext().sendBroadcast(intent);
116    }
117
118    public void addMenuItems(Menu menu, boolean showDisabled) {
119        MenuInflater inflater = new MenuInflater(getContext());
120        inflater.inflate(R.menu.settings, menu);
121        MenuItem item = menu.findItem(R.id.menu_settings);
122        item.setIntent(getSearchSettingsIntent());
123    }
124
125    public Intent getSearchSettingsIntent() {
126        Intent settings = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
127        settings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
128        settings.setPackage(getContext().getPackageName());
129        return settings;
130    }
131
132    public int getNextVoiceSearchHintIndex(int size) {
133            int i = getAndIncrementIntPreference(getSearchPreferences(),
134                    NEXT_VOICE_SEARCH_HINT_INDEX_PREF);
135            return i % size;
136    }
137
138    // TODO: Could this be made atomic to avoid races?
139    private static int getAndIncrementIntPreference(SharedPreferences prefs, String name) {
140        int i = prefs.getInt(name, 0);
141        prefs.edit().putInt(name, i + 1).commit();
142        return i;
143    }
144
145    public void resetVoiceSearchHintFirstSeenTime() {
146        getSearchPreferences().edit()
147                .putLong(FIRST_VOICE_HINT_DISPLAY_TIME, System.currentTimeMillis()).commit();
148    }
149
150    public boolean haveVoiceSearchHintsExpired(int currentVoiceSearchVersion) {
151        SharedPreferences prefs = getSearchPreferences();
152
153        if (currentVoiceSearchVersion != 0) {
154            long currentTime = System.currentTimeMillis();
155            int lastVoiceSearchVersion = prefs.getInt(LAST_SEEN_VOICE_SEARCH_VERSION, 0);
156            long firstHintTime = prefs.getLong(FIRST_VOICE_HINT_DISPLAY_TIME, 0);
157            if (firstHintTime == 0 || currentVoiceSearchVersion != lastVoiceSearchVersion) {
158                prefs.edit()
159                        .putInt(LAST_SEEN_VOICE_SEARCH_VERSION, currentVoiceSearchVersion)
160                        .putLong(FIRST_VOICE_HINT_DISPLAY_TIME, currentTime)
161                        .commit();
162                firstHintTime = currentTime;
163            }
164            if (currentTime - firstHintTime > getConfig().getVoiceSearchHintActivePeriod()) {
165                if (DBG) Log.d(TAG, "Voice seach hint period expired; not showing hints.");
166                return true;
167            } else {
168                return false;
169            }
170        } else {
171            if (DBG) Log.d(TAG, "Could not determine voice search version; not showing hints.");
172            return true;
173        }
174    }
175
176    public boolean allowWebSearchShortcuts() {
177        return true;
178    }
179
180}
181