QSB settings overhaul

- Put Google and Phone search settings on the same screen.

- Use a local preference for SHOW_WEB_SUGGESTIONS instead
  of the soon deprecated Settings.System.SHOW_WEB_SUGGESTIONS,
  see http://b/issue?id=3021480

- Refactor settings code to get rid of un-mockable static methods.

- Define options menus in XML.

- Use DialogPreference for "Clear shortcuts" dialog.

Bug: 3017828
Change-Id: I198d19f8df809adfb91cc0df1f2b11998451cd6b
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d678ccd..e5f3744 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -76,7 +76,7 @@
                 android:authorities="com.android.quicksearchbox.shortcuts">
         </provider>
 
-        <activity android:name=".SearchSettings"
+        <activity android:name=".SearchSettingsActivity"
                 android:label="@string/search_settings"
                 android:excludeFromRecents="true">
             <intent-filter>
@@ -86,6 +86,10 @@
                 <action android:name="android.search.action.SEARCH_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.search.action.WEB_SEARCH_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
         </activity>
 
         <activity android:name=".SearchableItemsSettings"
@@ -139,15 +143,6 @@
                 android:resource="@xml/google_searchable" />
         </activity>
 
-        <activity android:name=".google.GoogleSettings"
-                android:label="@string/google_search_settings"
-                android:excludeFromRecents="true">
-            <intent-filter>
-                <action android:name="android.search.action.WEB_SEARCH_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
         <provider android:name=".google.GoogleSuggestionProvider"
             android:label="@string/google_search_label"
             android:authorities="com.android.quicksearchbox.google" />
diff --git a/res/menu/settings.xml b/res/menu/settings.xml
new file mode 100644
index 0000000..617a5e3
--- /dev/null
+++ b/res/menu/settings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/menu_settings"
+        android:title="@string/menu_settings"
+        android:icon="@drawable/ic_menu_preferences"
+        android:alphabeticShortcut='P'
+        />
+</menu>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index aa466a2..69becbb 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Hledat aplikace"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Nastavení vyhledávání"</string>
     <string name="search_settings" msgid="4101951238194600323">"Nastavení vyhledávání"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Vyhledávatelné položky"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Zvolte, co vyhledávat v telefonu"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Vyhledávání Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Vyhledávání Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Návrhy vyhledávání Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Vyhledávání Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Zobrazovat návrhy webů"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Při psaní zobrazovat návrhy od Googlu"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Při psaní nezobrazovat návrhy od Googlu"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 611dfd9..3146332 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Søg i Apps"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Indstillinger for søgning"</string>
     <string name="search_settings" msgid="4101951238194600323">"Indstillinger for søgning"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Søgbare elementer"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Vælg, hvad der søges efter i telefonen"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google-søgning"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google-søgning"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google-søgeforslag"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google-søgning"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Vis webforslag"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Vis forslag fra Google under indtastning"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Vis ikke forslag fra Google under indtastning"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 9277abc..b7424fe 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Anwendungen durchsuchen"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Sucheinstellungen"</string>
     <string name="search_settings" msgid="4101951238194600323">"Sucheinstellungen"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Durchsuchbare Elemente"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Auswahl für die Suche auf dem Telefon"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google-Suche"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google-Suche"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google-Suchvorschläge"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google-Suche"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Webvorschläge anzeigen"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Vorschläge von Google während der Eingabe anzeigen"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Keine Vorschläge von Google während der Eingabe anzeigen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index c92fd23..9991762 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Αναζήτηση στις Εφαρμογές Google"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Ρυθμίσεις αναζήτησης"</string>
     <string name="search_settings" msgid="4101951238194600323">"Ρυθμίσεις αναζήτησης"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Ιστός"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Τηλέφωνο"</string>
     <string name="search_sources" msgid="505874718206340313">"Στοιχεία με δυνατότητα αναζήτησης"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Επιλέξτε το αντικείμενο αναζήτησης στο τηλέφωνο"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Αναζήτηση Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Αναζήτηση Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Προτάσεις αναζήτησης Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Αναζήτηση Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Εμφάνιση προτάσεων ιστού"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Να εμφανίζονται προτάσεις από το Google κατά την πληκτρολόγηση"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Να μην εμφανίζονται προτάσεις από το Google κατά την πληκτρολόγηση"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index ad9d6de..3dcd14c 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Buscar Google Apps"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Configuración de búsqueda"</string>
     <string name="search_settings" msgid="4101951238194600323">"Configuración de búsqueda"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Teléfono"</string>
     <string name="search_sources" msgid="505874718206340313">"Elementos de búsqueda"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Selecciona lo que deseas buscar en el teléfono."</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Búsqueda de Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Búsqueda de Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sugerencias de búsqueda de Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Búsqueda de Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Ver sugerencias web"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mostrar sugerencias de Google mientras escribes"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"No mostrar sugerencias de Google mientras escribes"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 0b1f21e..4e7eed0 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Buscar aplicaciones"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Ajustes de búsqueda"</string>
     <string name="search_settings" msgid="4101951238194600323">"Ajustes de búsqueda"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Búsqueda web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Teléfono"</string>
     <string name="search_sources" msgid="505874718206340313">"Elementos de búsqueda"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Elegir lo que se quiere buscar en el teléfono"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Búsqueda de Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Búsqueda de Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sugerencias de búsqueda de Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Búsqueda de Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Mostrar sugerencias web"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mostrar sugerencias de Google al escribir"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"No mostrar sugerencias de Google al escribir"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 5b09b31..4be4b35 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Rechercher dans les applications"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Paramètres de recherche"</string>
     <string name="search_settings" msgid="4101951238194600323">"Paramètres de recherche"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Téléphone"</string>
     <string name="search_sources" msgid="505874718206340313">"Sources"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Sélection des sources à explorer sur le téléphone lors d\'une recherche"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Recherche Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Recherche Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Suggestions de recherche Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Recherche Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Afficher les suggestions"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Afficher les suggestions de Google lors de la saisie"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Ne pas afficher les suggestions de Google lors de la saisie"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 9ba4ba1..93e3b97 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Cerca applicazioni"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Impostazioni ricerca"</string>
     <string name="search_settings" msgid="4101951238194600323">"Impostazioni ricerca"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefono"</string>
     <string name="search_sources" msgid="505874718206340313">"Elementi ricercabili"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Scegli che cosa cercare sul cellulare"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Ricerca Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Ricerca Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Suggerimenti di ricerca Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Ricerca Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Mostra suggerimenti"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mostra suggerimenti Google durante la digitazione"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Non mostrare suggerimenti da Google durante la digitazione"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index a4ca7aa..b19215d 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"アプリケーションを検索"</string>
     <string name="menu_settings" msgid="5600043319144155953">"検索設定"</string>
     <string name="search_settings" msgid="4101951238194600323">"検索設定"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"ウェブ"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"電話"</string>
     <string name="search_sources" msgid="505874718206340313">"検索対象"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"携帯内部の検索する対象を選択する"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google検索"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google検索"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Googleの検索候補"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google検索"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"入力候補の表示"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"入力時にGoogleの検索候補を表示する"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"入力時にGoogleの入力候補を表示しない"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d71bffc..0cc025d 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"애플리케이션 검색"</string>
     <string name="menu_settings" msgid="5600043319144155953">"검색 설정"</string>
     <string name="search_settings" msgid="4101951238194600323">"검색 설정"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"웹"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"휴대전화"</string>
     <string name="search_sources" msgid="505874718206340313">"검색 가능한 항목"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"휴대전화에서 검색할 항목 선택"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google 검색"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google 검색"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google 추천검색어"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google 검색"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"웹 추천검색어 표시"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"입력하는 동안 Google에서 추천검색어 표시"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"입력하는 동안 Google에서 추천검색어 표시 안함"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 09ddad9..476f7e7 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Søkeprogrammer"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Innstillinger for søk"</string>
     <string name="search_settings" msgid="4101951238194600323">"Innstillinger for søk"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Internett"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Søkbare elementer"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Velg hva du vil søke etter på telefonen"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google Søk"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google Søk"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google-søkeforslag"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google-søk"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Vis søkeforslag"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Vis forslag fra Google mens du skriver"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Ikke vis forslag fra Google mens du skriver"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 0c0646f..a13bcb9 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Zoeken in Google Apps"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Zoekinstellingen"</string>
     <string name="search_settings" msgid="4101951238194600323">"Zoekinstellingen"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefoon"</string>
     <string name="search_sources" msgid="505874718206340313">"Doorzoekbare items"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Kies wat u op de telefoon wilt zoeken"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google Zoeken"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google Zoeken"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Zoeksuggesties van Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google Zoeken"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Websuggesties tonen"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Suggesties van Google weergeven terwijl u typt"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Geen suggesties van Google weergeven terwijl u typt"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 6df75a2..f0cf29f 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Szukaj w aplikacjach"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Ustawienia wyszukiwania"</string>
     <string name="search_settings" msgid="4101951238194600323">"Ustawienia wyszukiwania"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Sieć"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Przeszukiwane elementy"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Wybierz elementy przeszukiwane w telefonie"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Wyszukiwarka Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Wyszukiwarka Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sugestie wyszukiwania Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Wyszukiwarka Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Pokazuj sugestie w sieci"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Pokazuj sugestie od Google podczas pisania"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Nie pokazuj sugestii od Google podczas pisania"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 154d160..826225b 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Pesquisar no Google Apps"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Definições de pesquisa"</string>
     <string name="search_settings" msgid="4101951238194600323">"Definições de pesquisa"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefone"</string>
     <string name="search_sources" msgid="505874718206340313">"Itens pesquisáveis"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Seleccionar os itens a pesquisar no telefone"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Pesquisa do Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Pesquisa do Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sugestões de pesquisa do Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Pesquisa do Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Mostrar sugestões da Web"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mostrar sugestões do Google enquanto escreve"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Não mostrar sugestões do Google enquanto escreve"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 73dd19f..64477d6 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Pesquisar aplicativos"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Configurações de pesquisa"</string>
     <string name="search_settings" msgid="4101951238194600323">"Configurações de pesquisa"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefone"</string>
     <string name="search_sources" msgid="505874718206340313">"Itens pesquisáveis"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Escolher o que deve ser pesquisado no telefone"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Pesquisa do Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Pesquisa do Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sugestões da pesquisa do Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Pesquisa do Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Sugestões da web"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mostrar sugestões do Google enquanto você digita"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Não mostrar sugestões do Google enquanto você digita"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 42aaace..b4bb940 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Tschertgar en las applicaziuns"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Parameters da tschertgar"</string>
     <string name="search_settings" msgid="4101951238194600323">"Parameters da tschertgar"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Funtaunas"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Tscherna da las funtaunas che duain vegnir retschertgadas"</string>
@@ -41,7 +40,6 @@
     <string name="google_search_hint" msgid="8374014384681586649">"Tschertga Google"</string>
     <!-- no translation found for google_search_description (6583849182671608994) -->
     <skip />
-    <string name="google_search_settings" msgid="4169698045412400949">"Tschertga Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Mussar las propostas web"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Mussar las propostas da Google durant l\'endataziun"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Betg mussar propostas da Google durant l\'endataziun"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index b11e0e2..a2cc253 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Поиск приложений"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Настройки поиска"</string>
     <string name="search_settings" msgid="4101951238194600323">"Настройки поиска"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Интернет"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Телефон"</string>
     <string name="search_sources" msgid="505874718206340313">"Источники поиска"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Выберите источники, по которым будет осуществляться поиск."</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Поиск Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Поиск Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Поисковые подсказки Google"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Поиск Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Поисковые подсказки"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Показывать подсказки при вводе поискового запроса"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Не показывать подсказки при вводе поискового запроса"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 7bdcd1e..bc62259 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Sök i Apps"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Sökinställningar"</string>
     <string name="search_settings" msgid="4101951238194600323">"Sökinställningar"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Webb"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Sökbara objekt"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Välj vad du vill söka efter med telefonen"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Sök på Google"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Sök på Google"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Sökförslag på Google "</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Sök på Google"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Visa webbförslag"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Visa förslag från Google medan du skriver"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Visa inte förslag från Google medan du skriver"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 66cb766..70ddc62 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"Google Apps\'ta Ara"</string>
     <string name="menu_settings" msgid="5600043319144155953">"Arama ayarları"</string>
     <string name="search_settings" msgid="4101951238194600323">"Arama ayarları"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"Web"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"Telefon"</string>
     <string name="search_sources" msgid="505874718206340313">"Aranabilir öğeler"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"Telefonda aranacak öğeleri seçin"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google Arama"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google Arama"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google arama önerileri"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google arama"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"Web önerilerini göster"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"Yazarken Google önerilerini göster"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"Yazarken Google önerilerini gösterme"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 995155a..46619ba 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"搜索应用程序"</string>
     <string name="menu_settings" msgid="5600043319144155953">"搜索设置"</string>
     <string name="search_settings" msgid="4101951238194600323">"搜索设置"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"网络"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"电话"</string>
     <string name="search_sources" msgid="505874718206340313">"可搜索的项"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"选择要在手机上搜索的内容"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google 搜索"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google 搜索"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google 搜索建议"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google 搜索"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"显示网页建议"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"输入时显示 Google 提供的建议"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"输入时不显示 Google 提供的建议"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 454e7ab..2a11ce0 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -27,7 +27,6 @@
     <string name="corpus_hint_apps" msgid="4230401643970165739">"搜尋應用程式"</string>
     <string name="menu_settings" msgid="5600043319144155953">"搜尋設定"</string>
     <string name="search_settings" msgid="4101951238194600323">"搜尋設定"</string>
-    <string name="web_search_category_title" msgid="3696363552067530526">"網頁"</string>
     <string name="system_search_category_title" msgid="1507902891285388819">"手機"</string>
     <string name="search_sources" msgid="505874718206340313">"可搜尋項目"</string>
     <string name="search_sources_summary" msgid="9181194249796408374">"選取要在手機上搜尋的內容"</string>
@@ -40,7 +39,6 @@
     <string name="google_app_label" msgid="7877830942664670350">"Google 搜尋"</string>
     <string name="google_search_hint" msgid="8374014384681586649">"Google 搜尋"</string>
     <string name="google_search_description" msgid="6583849182671608994">"Google 搜尋建議"</string>
-    <string name="google_search_settings" msgid="4169698045412400949">"Google 搜尋"</string>
     <string name="google_show_web_suggestions" msgid="9018281734662733247">"顯示網頁建議"</string>
     <string name="google_show_web_suggestions_summary_enabled" msgid="6978457517649501505">"輸入時顯示 Google 提供的建議"</string>
     <string name="google_show_web_suggestions_summary_disabled" msgid="3768151514600543003">"輸入時不要顯示 Google 提供的建議"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d49f25c..be7d529 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -45,8 +45,9 @@
     <!-- Search settings title -->
     <string name="search_settings">Search settings</string>
 
-    <!-- Title for 'web search' category of search settings -->
-    <string name="web_search_category_title">Web</string>
+    <!-- Title for 'Google' category of search settings.
+         [CHAR LIMIT=20] -->
+    <string name="google_search_category_title">Google</string>
 
     <!-- Title for 'system search' category of search settings -->
     <string name="system_search_category_title">Phone</string>
@@ -80,9 +81,6 @@
     <!-- Search settings description for the Google search source. -->
     <string name="google_search_description">Google search suggestions</string>
 
-    <!-- Settings category title for 'Google search settings' settings activity -->
-    <string name="google_search_settings">Google search</string>
-
     <!-- Title and summaries for 'show web suggestions' check box setting -->
     <string name="google_show_web_suggestions">Show web suggestions</string>
     <string name="google_show_web_suggestions_summary_enabled">Show suggestions from Google as you type</string>
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index dbcdc35..03491f8 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -18,28 +18,39 @@
         xmlns:android="http://schemas.android.com/apk/res/android">
 
     <PreferenceCategory
-            android:title="@string/web_search_category_title">
-            
-        <PreferenceScreen
-                android:key="search_engine_settings" />
-
-    </PreferenceCategory>
-    
-    <PreferenceCategory
             android:title="@string/system_search_category_title">
 
         <PreferenceScreen
                 android:key="search_corpora"
                 android:title="@string/search_sources"
-                android:summary="@string/search_sources_summary" />
+                android:summary="@string/search_sources_summary"
+                />
 
-        <!-- TODO: Use DialogPreference instead. -->
-        <Preference
+        <com.android.quicksearchbox.OkCancelPreference
                 android:key="clear_shortcuts"
                 android:persistent="false"
-                android:title="@string/clear_shortcuts" 
-                android:summary="@string/clear_shortcuts_summary" />
-                
+                android:title="@string/clear_shortcuts"
+                android:summary="@string/clear_shortcuts_summary"
+                android:dialogTitle="@string/clear_shortcuts"
+                android:dialogMessage="@string/clear_shortcuts_prompt"
+                android:positiveButtonText="@string/agree"
+                android:negativeButtonText="@string/disagree"
+                />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:key="google_settings"
+            android:title="@string/google_search_category_title">
+
+        <CheckBoxPreference
+                android:key="show_web_suggestions"
+                android:title="@string/google_show_web_suggestions"
+                android:summaryOn="@string/google_show_web_suggestions_summary_enabled"
+                android:summaryOff="@string/google_show_web_suggestions_summary_disabled"
+                android:defaultValue="true"
+                />
+
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/src/com/android/quicksearchbox/AbstractCorpus.java b/src/com/android/quicksearchbox/AbstractCorpus.java
index 2e72b02..f63295c 100644
--- a/src/com/android/quicksearchbox/AbstractCorpus.java
+++ b/src/com/android/quicksearchbox/AbstractCorpus.java
@@ -17,7 +17,6 @@
 package com.android.quicksearchbox;
 
 import android.content.Context;
-import android.content.SharedPreferences;
 
 
 /**
@@ -38,13 +37,6 @@
         return mContext;
     }
 
-    public boolean isCorpusEnabled() {
-        boolean defaultEnabled = isCorpusDefaultEnabled();
-        String sourceEnabledPref = SearchSettings.getCorpusEnabledPreference(this);
-        SharedPreferences prefs = SearchSettings.getSearchPreferences(mContext);
-        return prefs.getBoolean(sourceEnabledPref, defaultEnabled);
-    }
-
     public boolean isCorpusDefaultEnabled() {
         return mConfig.isCorpusEnabledByDefault(this);
     }
diff --git a/src/com/android/quicksearchbox/Corpus.java b/src/com/android/quicksearchbox/Corpus.java
index 1affbe0..e7fef27 100644
--- a/src/com/android/quicksearchbox/Corpus.java
+++ b/src/com/android/quicksearchbox/Corpus.java
@@ -80,11 +80,6 @@
     Collection<Source> getSources();
 
     /**
-     * Checks if this corpus is enabled.
-     */
-    boolean isCorpusEnabled();
-
-    /**
      * Checks if this corpus is enabled by default.
      */
     boolean isCorpusDefaultEnabled();
diff --git a/src/com/android/quicksearchbox/CorpusSelectionDialog.java b/src/com/android/quicksearchbox/CorpusSelectionDialog.java
index c3712aa..c952ed2 100644
--- a/src/com/android/quicksearchbox/CorpusSelectionDialog.java
+++ b/src/com/android/quicksearchbox/CorpusSelectionDialog.java
@@ -17,7 +17,6 @@
 package com.android.quicksearchbox;
 
 import com.android.quicksearchbox.ui.CorporaAdapter;
-import com.android.quicksearchbox.ui.CorpusViewFactory;
 
 import android.app.Dialog;
 import android.content.Context;
@@ -42,6 +41,8 @@
     private static final boolean DBG = false;
     private static final String TAG = "QSB.SelectSearchSourceDialog";
 
+    private final SearchSettings mSettings;
+
     private GridView mCorpusGrid;
 
     private ImageView mEditItems;
@@ -52,8 +53,13 @@
 
     private CorporaAdapter mAdapter;
 
-    public CorpusSelectionDialog(Context context) {
+    public CorpusSelectionDialog(Context context, SearchSettings settings) {
         super(context, R.style.Theme_SelectSearchSource);
+        mSettings = settings;
+    }
+
+    protected SearchSettings getSettings() {
+        return mSettings;
     }
 
     /**
@@ -109,7 +115,14 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-        SearchSettings.addSearchSettingsMenuItem(getContext(), menu);
+        getSettings().addMenuItems(menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        getSettings().updateMenuItems(menu);
         return true;
     }
 
@@ -187,7 +200,7 @@
 
     private class CorpusEditListener implements View.OnClickListener {
         public void onClick(View v) {
-            Intent intent = SearchSettings.getSearchableItemsIntent(getContext());
+            Intent intent = getSettings().getSearchableItemsIntent();
             getContext().startActivity(intent);
         }
     }
diff --git a/src/com/android/quicksearchbox/OkCancelPreference.java b/src/com/android/quicksearchbox/OkCancelPreference.java
new file mode 100644
index 0000000..14c4feb
--- /dev/null
+++ b/src/com/android/quicksearchbox/OkCancelPreference.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quicksearchbox;
+
+import android.content.Context;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+
+/**
+ * Dialog preference that allows registering a listener for the result.
+ */
+public class OkCancelPreference extends DialogPreference {
+
+    private Listener mListener;
+
+    public OkCancelPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (mListener != null) {
+            mListener.onDialogClosed(positiveResult);
+        }
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public interface Listener {
+        void onDialogClosed(boolean okClicked);
+    }
+
+}
diff --git a/src/com/android/quicksearchbox/QsbApplication.java b/src/com/android/quicksearchbox/QsbApplication.java
index b7bff8e..57969d3 100644
--- a/src/com/android/quicksearchbox/QsbApplication.java
+++ b/src/com/android/quicksearchbox/QsbApplication.java
@@ -48,6 +48,7 @@
     private int mVersionCode;
     private Handler mUiThreadHandler;
     private Config mConfig;
+    private SearchSettings mSettings;
     private Sources mSources;
     private Corpora mCorpora;
     private CorpusRanker mCorpusRanker;
@@ -154,6 +155,18 @@
         return new Config(getContext());
     }
 
+    public synchronized SearchSettings getSettings() {
+        if (mSettings == null) {
+            mSettings = createSettings();
+            mSettings.upgradeSettingsIfNeeded();
+        }
+        return mSettings;
+    }
+
+    protected SearchSettings createSettings() {
+        return new SearchSettingsImpl(getContext(), getConfig());
+    }
+
     /**
      * Gets all corpora.
      *
@@ -168,7 +181,7 @@
     }
 
     protected Corpora createCorpora(Sources sources) {
-        SearchableCorpora corpora = new SearchableCorpora(getContext(), sources,
+        SearchableCorpora corpora = new SearchableCorpora(getContext(), getSettings(), sources,
                 createCorpusFactory());
         corpora.update();
         return corpora;
@@ -199,7 +212,7 @@
 
     protected CorpusFactory createCorpusFactory() {
         int numWebCorpusThreads = getConfig().getNumWebCorpusThreads();
-        return new SearchableCorpusFactory(getContext(), getConfig(),
+        return new SearchableCorpusFactory(getContext(), getConfig(), getSettings(),
                 createExecutorFactory(numWebCorpusThreads));
     }
 
diff --git a/src/com/android/quicksearchbox/SearchActivity.java b/src/com/android/quicksearchbox/SearchActivity.java
index 730a8e3..04e2277 100644
--- a/src/com/android/quicksearchbox/SearchActivity.java
+++ b/src/com/android/quicksearchbox/SearchActivity.java
@@ -259,6 +259,10 @@
         return getQsbApplication().getConfig();
     }
 
+    protected SearchSettings getSettings() {
+        return getQsbApplication().getSettings();
+    }
+
     private Corpora getCorpora() {
         return getQsbApplication().getCorpora();
     }
@@ -330,7 +334,14 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
-        SearchSettings.addSearchSettingsMenuItem(this, menu);
+        getSettings().addMenuItems(menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        getSettings().updateMenuItems(menu);
         return true;
     }
 
@@ -359,7 +370,7 @@
     }
 
     protected CorpusSelectionDialog createCorpusSelectionDialog() {
-        return new CorpusSelectionDialog(this);
+        return new CorpusSelectionDialog(this, getSettings());
     }
 
     /**
@@ -414,7 +425,7 @@
     }
 
     protected void onSettingsClicked() {
-        SearchSettings.launchSettings(this);
+        startActivity(getSettings().getSearchSettingsIntent());
     }
 
     protected Corpus getSearchCorpus() {
diff --git a/src/com/android/quicksearchbox/SearchSettings.java b/src/com/android/quicksearchbox/SearchSettings.java
index 7f78eaf..1d3795d 100644
--- a/src/com/android/quicksearchbox/SearchSettings.java
+++ b/src/com/android/quicksearchbox/SearchSettings.java
@@ -16,227 +16,37 @@
 
 package com.android.quicksearchbox;
 
-import com.android.quicksearchbox.util.Consumer;
-import com.android.quicksearchbox.util.Consumers;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.SearchManager;
-import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.provider.Settings;
-import android.provider.Settings.System;
-import android.util.Log;
 import android.view.Menu;
 
-import java.util.List;
-
 /**
- * Activity for setting global search preferences.
+ * Interface for search settings.
  */
-public class SearchSettings extends PreferenceActivity
-        implements OnPreferenceClickListener {
+public interface SearchSettings {
 
-    private static final boolean DBG = false;
-    private static final String TAG = "SearchSettings";
+    public void upgradeSettingsIfNeeded();
 
-    // Name of the preferences file used to store search preference
-    public static final String PREFERENCES_NAME = "SearchSettings";
+    public Intent getSearchableItemsIntent();
 
-    // Intent action that opens the "Searchable Items" preference
-    public static final String ACTION_SEARCHABLE_ITEMS =
-            "com.android.quicksearchbox.action.SEARCHABLE_ITEMS";
+    public boolean isCorpusEnabled(Corpus corpus);
 
-    // Only used to find the preferences after inflating
-    private static final String CLEAR_SHORTCUTS_PREF = "clear_shortcuts";
-    private static final String SEARCH_ENGINE_SETTINGS_PREF = "search_engine_settings";
-    private static final String SEARCH_CORPORA_PREF = "search_corpora";
-
-    // Prefix of per-corpus enable preference
-    private static final String CORPUS_ENABLED_PREF_PREFIX = "enable_corpus_";
-
-    // References to the top-level preference objects
-    private Preference mClearShortcutsPreference;
-    private PreferenceScreen mSearchEngineSettingsPreference;
-
-    // Dialog ids
-    private static final int CLEAR_SHORTCUTS_CONFIRM_DIALOG = 0;
-
-    private Handler mHandler = new Handler();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        getPreferenceManager().setSharedPreferencesName(PREFERENCES_NAME);
-
-        addPreferencesFromResource(R.xml.preferences);
-
-        PreferenceScreen preferenceScreen = getPreferenceScreen();
-        mClearShortcutsPreference = preferenceScreen.findPreference(CLEAR_SHORTCUTS_PREF);
-        mSearchEngineSettingsPreference = (PreferenceScreen) preferenceScreen.findPreference(
-                SEARCH_ENGINE_SETTINGS_PREF);
-        Preference corporaPreference = preferenceScreen.findPreference(SEARCH_CORPORA_PREF);
-        corporaPreference.setIntent(getSearchableItemsIntent(this));
-
-        mClearShortcutsPreference.setOnPreferenceClickListener(this);
-
-        updateClearShortcutsPreference();
-        populateSearchEnginePreference();
-    }
-
-    public static Intent getSearchableItemsIntent(Context context) {
-        Intent intent = new Intent(SearchSettings.ACTION_SEARCHABLE_ITEMS);
-        intent.setPackage(context.getPackageName());
-        return intent;
-    }
-
-    /**
-     * Gets the preference key of the preference for whether the given corpus
-     * is enabled. The preference is stored in the {@link #PREFERENCES_NAME}
-     * preferences file.
-     */
-    public static String getCorpusEnabledPreference(Corpus corpus) {
-        return CORPUS_ENABLED_PREF_PREFIX + corpus.getName();
-    }
-
-    public static SharedPreferences getSearchPreferences(Context context) {
-        return context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
-    }
-
-    private ShortcutRepository getShortcuts() {
-        return QsbApplication.get(this).getShortcutRepository();
-    }
-
-    /**
-     * Enables/disables the "Clear search shortcuts" preference depending
-     * on whether there is any search history.
-     */
-    private void updateClearShortcutsPreference() {
-        getShortcuts().hasHistory(Consumers.createAsyncConsumer(mHandler, new Consumer<Boolean>() {
-            @Override
-            public boolean consume(Boolean hasHistory) {
-                if (DBG) Log.d(TAG, "hasHistory()=" + hasHistory);
-                mClearShortcutsPreference.setEnabled(hasHistory);
-                return true;
-            }
-        }));
-    }
-
-    /**
-     * Populates the preference item for the web search engine, which links to further
-     * search settings.
-     */
-    private void populateSearchEnginePreference() {
-        Intent intent = new Intent(SearchManager.INTENT_ACTION_WEB_SEARCH_SETTINGS);
-        intent.setPackage(getPackageName());
-
-        CharSequence webSearchSettingsLabel = getActivityLabel(intent);
-        mSearchEngineSettingsPreference.setTitle(webSearchSettingsLabel);
-        mSearchEngineSettingsPreference.setIntent(intent);
-    }
-
-    private CharSequence getActivityLabel(Intent intent) {
-        PackageManager pm = getPackageManager();
-        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
-        if (resolveInfos.size() == 0) {
-            Log.e(TAG, "No web search settings activity");
-            return null;
-        }
-        if (resolveInfos.size() > 1) {
-            Log.e(TAG, "More than one web search settings activity");
-            return null;
-        }
-        return resolveInfos.get(0).activityInfo.loadLabel(pm);
-    }
-
-    public synchronized boolean onPreferenceClick(Preference preference) {
-        if (preference == mClearShortcutsPreference) {
-            showDialog(CLEAR_SHORTCUTS_CONFIRM_DIALOG);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id, Bundle args) {
-        switch (id) {
-            case CLEAR_SHORTCUTS_CONFIRM_DIALOG:
-                return new AlertDialog.Builder(this)
-                        .setTitle(R.string.clear_shortcuts)
-                        .setMessage(R.string.clear_shortcuts_prompt)
-                        .setPositiveButton(R.string.agree, new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                if (DBG) Log.d(TAG, "Clearing history...");
-                                getShortcuts().clearHistory();
-                                mClearShortcutsPreference.setEnabled(false);
-                            }
-                        })
-                        .setNegativeButton(R.string.disagree, null).create();
-            default:
-                Log.e(TAG, "unknown dialog" + id);
-                return null;
-        }
-    }
+    public boolean getShowWebSuggestions();
 
     /**
      * Informs our listeners about the updated settings data.
      */
-    public static void broadcastSettingsChanged(Context context) {
-        // We use a message broadcast since the listeners could be in multiple processes.
-        Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS_CHANGED);
-        Log.i(TAG, "Broadcasting: " + intent);
-        context.sendBroadcast(intent);
-    }
+    public void broadcastSettingsChanged();
 
-    public static boolean getShowWebSuggestions(Context context) {
-        return (Settings.System.getInt(context.getContentResolver(),
-                Settings.System.SHOW_WEB_SUGGESTIONS,
-                1 /* default on until user actually changes it */) == 1);
-    }
+    public void addMenuItems(Menu menu);
 
-    public static void setShowWebSuggestions(Context context, boolean showWebSuggestions) {
-        System.putInt(context.getContentResolver(), System.SHOW_WEB_SUGGESTIONS,
-            showWebSuggestions ? 1 : 0);
-    }
+    public void updateMenuItems(Menu menu);
 
-    public static void registerShowWebSuggestionsSettingObserver(
-            Context context, ContentObserver observer) {
-        context.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.SHOW_WEB_SUGGESTIONS),
-                false, observer);
-    }
+    public int getNextVoiceSearchHintIndex(int size);
 
-    public static void unregisterShowWebSuggestionsSettingObserver(
-            Context context, ContentObserver observer) {
-        context.getContentResolver().unregisterContentObserver(observer);
-    }
+    public void resetVoiceSearchHintFirstSeenTime();
 
-    public static void addSearchSettingsMenuItem(Context context, Menu menu) {
-        Intent settings = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
-        settings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-        // Don't show activity chooser if there are multiple search settings activities,
-        // e.g. from different QSB implementations.
-        settings.setPackage(context.getPackageName());
-        menu.add(Menu.NONE, Menu.NONE, 0, R.string.menu_settings)
-                .setIcon(R.drawable.ic_menu_preferences).setAlphabeticShortcut('P')
-                .setIntent(settings);
-    }
+    public boolean haveVoiceSearchHintsExpired(int currentVoiceSearchVersion);
 
-    public static void launchSettings(Context context) {
-        Intent settings = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
-        settings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-        context.startActivity(settings);
-    }
+    public Intent getSearchSettingsIntent();
+
 }
diff --git a/src/com/android/quicksearchbox/SearchSettingsActivity.java b/src/com/android/quicksearchbox/SearchSettingsActivity.java
new file mode 100644
index 0000000..f06d85f
--- /dev/null
+++ b/src/com/android/quicksearchbox/SearchSettingsActivity.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quicksearchbox;
+
+import com.android.quicksearchbox.util.Consumer;
+import com.android.quicksearchbox.util.Consumers;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+
+/**
+ * Activity for setting global search preferences.
+ */
+public class SearchSettingsActivity extends PreferenceActivity
+        implements OnPreferenceClickListener, OnPreferenceChangeListener {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "QSB.SearchSettingsActivity";
+
+    // Name of the preferences file used to store search preference
+    public static final String PREFERENCES_NAME = "SearchSettings";
+
+    // Intent action that opens the "Searchable Items" preference
+    public static final String ACTION_SEARCHABLE_ITEMS =
+            "com.android.quicksearchbox.action.SEARCHABLE_ITEMS";
+
+    // Only used to find the preferences after inflating
+    private static final String CLEAR_SHORTCUTS_PREF = "clear_shortcuts";
+    private static final String SEARCH_CORPORA_PREF = "search_corpora";
+
+    // References to the top-level preference objects
+    private OkCancelPreference mClearShortcutsPreference;
+
+    private Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getPreferenceManager().setSharedPreferencesName(PREFERENCES_NAME);
+
+        addPreferencesFromResource(R.xml.preferences);
+
+        mClearShortcutsPreference =
+                (OkCancelPreference) findPreference(CLEAR_SHORTCUTS_PREF);
+        mClearShortcutsPreference.setListener(new OkCancelPreference.Listener() {
+            @Override
+            public void onDialogClosed(boolean okClicked) {
+                if (okClicked) {
+                    clearShortcuts();
+                }
+            }
+        });
+
+        Preference corporaPreference = findPreference(SEARCH_CORPORA_PREF);
+        corporaPreference.setIntent(getSettings().getSearchableItemsIntent());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        updateClearShortcutsPreference();
+    }
+
+    private SearchSettings getSettings() {
+        return QsbApplication.get(this).getSettings();
+    }
+
+    private ShortcutRepository getShortcuts() {
+        return QsbApplication.get(this).getShortcutRepository();
+    }
+
+    /**
+     * Enables/disables the "Clear search shortcuts" preference depending
+     * on whether there is any search history.
+     */
+    private void updateClearShortcutsPreference() {
+        getShortcuts().hasHistory(Consumers.createAsyncConsumer(mHandler, new Consumer<Boolean>() {
+            @Override
+            public boolean consume(Boolean hasHistory) {
+                if (DBG) Log.d(TAG, "hasHistory()=" + hasHistory);
+                mClearShortcutsPreference.setEnabled(hasHistory);
+                return true;
+            }
+        }));
+    }
+
+    public boolean onPreferenceClick(Preference preference) {
+        return false;
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        return true;
+    }
+
+    private void clearShortcuts() {
+        Log.i(TAG, "Clearing shortcuts...");
+        getShortcuts().clearHistory();
+        mClearShortcutsPreference.setEnabled(false);
+    }
+
+}
diff --git a/src/com/android/quicksearchbox/SearchSettingsImpl.java b/src/com/android/quicksearchbox/SearchSettingsImpl.java
new file mode 100644
index 0000000..c138cc6
--- /dev/null
+++ b/src/com/android/quicksearchbox/SearchSettingsImpl.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quicksearchbox;
+
+import android.app.SearchManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+/**
+ * Manages user settings.
+ */
+public class SearchSettingsImpl implements SearchSettings {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "QSB.SearchSettingsImpl";
+
+    // Name of the preferences file used to store search preference
+    public static final String PREFERENCES_NAME = "SearchSettings";
+
+    // Intent action that opens the "Searchable Items" preference
+    private static final String ACTION_SEARCHABLE_ITEMS =
+            "com.android.quicksearchbox.action.SEARCHABLE_ITEMS";
+
+    private static final String SHOW_WEB_SUGGESTIONS_PREF = "show_web_suggestions";
+
+    /**
+     * Preference key used for storing the index of the next voice search hint to show.
+     */
+    private static final String NEXT_VOICE_SEARCH_HINT_INDEX_PREF = "next_voice_search_hint";
+
+    /**
+     * Preference key used to store the time at which the first voice search hint was displayed.
+     */
+    private static final String FIRST_VOICE_HINT_DISPLAY_TIME = "first_voice_search_hint_time";
+
+    /**
+     * Preference key for the version of voice search we last got hints from.
+     */
+    private static final String LAST_SEEN_VOICE_SEARCH_VERSION = "voice_search_version";
+
+    /**
+     * Prefix of per-corpus enable preference
+     */
+    private static final String CORPUS_ENABLED_PREF_PREFIX = "enable_corpus_";
+
+    private final Context mContext;
+
+    private final Config mConfig;
+
+    public SearchSettingsImpl(Context context, Config config) {
+        mContext = context;
+        mConfig = config;
+    }
+
+    protected Context getContext() {
+        return mContext;
+    }
+
+    protected Config getConfig() {
+        return mConfig;
+    }
+
+    public void upgradeSettingsIfNeeded() {
+        upgradeShowWebSuggestionsIfNeeded();
+    }
+
+    public Intent getSearchableItemsIntent() {
+        Intent intent = new Intent(ACTION_SEARCHABLE_ITEMS);
+        intent.setPackage(getContext().getPackageName());
+        return intent;
+    }
+
+    /**
+     * Gets the preference key of the preference for whether the given corpus
+     * is enabled. The preference is stored in the {@link #PREFERENCES_NAME}
+     * preferences file.
+     */
+    public static String getCorpusEnabledPreference(Corpus corpus) {
+        return CORPUS_ENABLED_PREF_PREFIX + corpus.getName();
+    }
+
+    public boolean isCorpusEnabled(Corpus corpus) {
+        boolean defaultEnabled = corpus.isCorpusDefaultEnabled();
+        String sourceEnabledPref = getCorpusEnabledPreference(corpus);
+        return getSearchPreferences().getBoolean(sourceEnabledPref, defaultEnabled);
+    }
+
+    protected SharedPreferences getSearchPreferences() {
+        return getContext().getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
+    }
+
+    public boolean getShowWebSuggestions() {
+        return getSearchPreferences().getBoolean(SHOW_WEB_SUGGESTIONS_PREF, true);
+    }
+
+    /**
+     * Copies value from the old deprecated SHOW_WEB_SUGGESTIONS system setting.
+     */
+    private void upgradeShowWebSuggestionsIfNeeded() {
+        SharedPreferences prefs = getSearchPreferences();
+        if (!prefs.contains(SHOW_WEB_SUGGESTIONS_PREF)) {
+            // Default to true if the old setting is not set
+            boolean oldValue = Settings.System.getInt(getContext().getContentResolver(),
+                    Settings.System.SHOW_WEB_SUGGESTIONS, 1) == 1;
+            prefs.edit().putBoolean(SHOW_WEB_SUGGESTIONS_PREF, oldValue).commit();
+            Log.i(TAG, "Copied value from Settings.System.SHOW_WEB_SUGGESTIONS: " + oldValue);
+        }
+    }
+
+    /**
+     * Informs our listeners about the updated settings data.
+     */
+    public void broadcastSettingsChanged() {
+        // We use a message broadcast since the listeners could be in multiple processes.
+        Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS_CHANGED);
+        Log.i(TAG, "Broadcasting: " + intent);
+        getContext().sendBroadcast(intent);
+    }
+
+    public void addMenuItems(Menu menu) {
+        MenuInflater inflater = new MenuInflater(getContext());
+        inflater.inflate(R.menu.settings, menu);
+        MenuItem item = menu.findItem(R.id.menu_settings);
+        item.setIntent(getSearchSettingsIntent());
+    }
+
+    public void updateMenuItems(Menu menu) {
+    }
+
+    public Intent getSearchSettingsIntent() {
+        Intent settings = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
+        settings.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+        settings.setPackage(getContext().getPackageName());
+        return settings;
+    }
+
+    public int getNextVoiceSearchHintIndex(int size) {
+            int i = getAndIncrementIntPreference(getSearchPreferences(),
+                    NEXT_VOICE_SEARCH_HINT_INDEX_PREF);
+            return i % size;
+    }
+
+    // TODO: Could this be made atomic to avoid races?
+    private static int getAndIncrementIntPreference(SharedPreferences prefs, String name) {
+        int i = prefs.getInt(name, 0);
+        prefs.edit().putInt(name, i + 1).commit();
+        return i;
+    }
+
+    public void resetVoiceSearchHintFirstSeenTime() {
+        getSearchPreferences().edit()
+                .putLong(FIRST_VOICE_HINT_DISPLAY_TIME, System.currentTimeMillis()).commit();
+    }
+
+    public boolean haveVoiceSearchHintsExpired(int currentVoiceSearchVersion) {
+        SharedPreferences prefs = getSearchPreferences();
+
+        if (currentVoiceSearchVersion != 0) {
+            long currentTime = System.currentTimeMillis();
+            int lastVoiceSearchVersion = prefs.getInt(LAST_SEEN_VOICE_SEARCH_VERSION, 0);
+            long firstHintTime = prefs.getLong(FIRST_VOICE_HINT_DISPLAY_TIME, 0);
+            if (firstHintTime == 0 || currentVoiceSearchVersion != lastVoiceSearchVersion) {
+                prefs.edit()
+                        .putInt(LAST_SEEN_VOICE_SEARCH_VERSION, currentVoiceSearchVersion)
+                        .putLong(FIRST_VOICE_HINT_DISPLAY_TIME, currentTime)
+                        .commit();
+                firstHintTime = currentTime;
+            }
+            if (currentTime - firstHintTime > getConfig().getVoiceSearchHintActivePeriod()) {
+                if (DBG) Log.d(TAG, "Voice seach hint period expired; not showing hints.");
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            if (DBG) Log.d(TAG, "Could not determine voice search version; not showing hints.");
+            return true;
+        }
+    }
+
+}
diff --git a/src/com/android/quicksearchbox/SearchWidgetProvider.java b/src/com/android/quicksearchbox/SearchWidgetProvider.java
index 8b77c4d..0cb65ba 100644
--- a/src/com/android/quicksearchbox/SearchWidgetProvider.java
+++ b/src/com/android/quicksearchbox/SearchWidgetProvider.java
@@ -29,8 +29,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
 import android.graphics.Typeface;
 import android.net.Uri;
 import android.os.Bundle;
@@ -90,21 +88,6 @@
             "com.android.quicksearchbox.action.debugonly.SHOW_HINT_TEMPORARILY";
 
     /**
-     * Preference key used for storing the index of the next voice search hint to show.
-     */
-    private static final String NEXT_VOICE_SEARCH_HINT_INDEX_PREF = "next_voice_search_hint";
-
-    /**
-     * Preference key used to store the time at which the first voice search hint was displayed.
-     */
-    private static final String FIRST_VOICE_HINT_DISPLAY_TIME = "first_voice_search_hint_time";
-
-    /**
-     * Preference key for the version of voice search we last got hints from.
-     */
-    private static final String LAST_SEEN_VOICE_SEARCH_VERSION = "voice_search_version";
-
-    /**
      * The {@link Search#SOURCE} value used when starting searches from the search widget.
      */
     private static final String WIDGET_SEARCH_SOURCE = "launcher-widget";
@@ -127,11 +110,11 @@
             hideVoiceSearchHint(context);
         } else if (ACTION_SHOW_VOICE_SEARCH_HINT_NOW.equals(action)) {
             showVoiceSearchHintNow(context);
-            resetVoiceSearchHintFirstSeenTime(context);
+            getSettings(context).resetVoiceSearchHintFirstSeenTime();
         } else if (ACTION_SHOW_HINT_TEMPORARILY.equals(action)) {
             showVoiceSearchHintNow(context);
         } else if (ACTION_RESET_VOICE_SEARCH_HINT_FIRST_SEEN.equals(action)) {
-            resetVoiceSearchHintFirstSeenTime(context);
+            getSettings(context).resetVoiceSearchHintFirstSeenTime();
         } else {
             if (DBG) Log.d(TAG, "Unhandled intent action=" + action);
         }
@@ -144,44 +127,10 @@
         return sRandom;
     }
 
-    private static void resetVoiceSearchHintFirstSeenTime(Context context) {
-        SharedPreferences prefs = SearchSettings.getSearchPreferences(context);
-        Editor e = prefs.edit();
-        e.putLong(FIRST_VOICE_HINT_DISPLAY_TIME, System.currentTimeMillis());
-        e.commit();
-    }
-
-    private static boolean haveVoiceSearchHintsExpired(Context context) {
-        SharedPreferences prefs = SearchSettings.getSearchPreferences(context);
-        QsbApplication app = QsbApplication.get(context);
-        int currentVoiceSearchVersion = app.getVoiceSearch().getVersion();
-
-        if (currentVoiceSearchVersion != 0) {
-            long currentTime = System.currentTimeMillis();
-            int lastVoiceSearchVersion = prefs.getInt(LAST_SEEN_VOICE_SEARCH_VERSION, 0);
-            long firstHintTime = prefs.getLong(FIRST_VOICE_HINT_DISPLAY_TIME, 0);
-            if (firstHintTime == 0 || currentVoiceSearchVersion != lastVoiceSearchVersion) {
-                Editor e = prefs.edit();
-                e.putInt(LAST_SEEN_VOICE_SEARCH_VERSION, currentVoiceSearchVersion);
-                e.putLong(FIRST_VOICE_HINT_DISPLAY_TIME, currentTime);
-                e.commit();
-                firstHintTime = currentTime;
-            }
-            if (currentTime - firstHintTime > getConfig(context).getVoiceSearchHintActivePeriod()) {
-                if (DBG) Log.d(TAG, "Voice seach hint period expired; not showing hints.");
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            if (DBG) Log.d(TAG, "Could not determine voice search version; not showing hints.");
-            return true;
-        }
-    }
-
     private static boolean shouldShowVoiceSearchHints(Context context) {
         return (getConfig(context).allowVoiceSearchHints()
-                && !haveVoiceSearchHintsExpired(context));
+                && !getSettings(context).haveVoiceSearchHintsExpired(
+                        getVoiceSearch(context).getVersion()));
     }
 
     private static SearchWidgetState[] getSearchWidgetStates
@@ -464,28 +413,18 @@
      */
     private static CharSequence getNextHint(Context context, ArrayList<CharSequence> hints) {
         if (hints == null || hints.isEmpty()) return null;
-        int i = getNextVoiceSearchHintIndex(context, hints.size());
+        int i = getSettings(context).getNextVoiceSearchHintIndex(hints.size());
         return hints.get(i);
     }
 
-    private static int getNextVoiceSearchHintIndex(Context context, int size) {
-        int i = getAndIncrementIntPreference(
-                SearchSettings.getSearchPreferences(context),
-                NEXT_VOICE_SEARCH_HINT_INDEX_PREF);
-        return i % size;
-    }
-
-    // TODO: Could this be made atomic to avoid races?
-    private static int getAndIncrementIntPreference(SharedPreferences prefs, String name) {
-        int i = prefs.getInt(name, 0);
-        prefs.edit().putInt(name, i + 1).commit();
-        return i;
-    }
-
     private static Config getConfig(Context context) {
         return QsbApplication.get(context).getConfig();
     }
 
+    private static SearchSettings getSettings(Context context) {
+        return QsbApplication.get(context).getSettings();
+    }
+
     private static Corpora getCorpora(Context context) {
         return QsbApplication.get(context).getCorpora();
     }
@@ -494,6 +433,10 @@
         return QsbApplication.get(context).getCorpusViewFactory();
     }
 
+    private static VoiceSearch getVoiceSearch(Context context) {
+        return QsbApplication.get(context).getVoiceSearch();
+    }
+
     private static class SearchWidgetState {
         private final int mAppWidgetId;
         private Uri mCorpusIconUri;
diff --git a/src/com/android/quicksearchbox/SearchableCorpora.java b/src/com/android/quicksearchbox/SearchableCorpora.java
index f52a201..d3b21c5 100644
--- a/src/com/android/quicksearchbox/SearchableCorpora.java
+++ b/src/com/android/quicksearchbox/SearchableCorpora.java
@@ -17,6 +17,7 @@
 package com.android.quicksearchbox;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.database.DataSetObservable;
 import android.database.DataSetObserver;
 import android.text.TextUtils;
@@ -40,6 +41,7 @@
     private final DataSetObservable mDataSetObservable = new DataSetObservable();
 
     private final Context mContext;
+    private final SearchSettings mSettings;
     private final CorpusFactory mCorpusFactory;
 
     private Sources mSources;
@@ -56,8 +58,10 @@
      *
      * @param context Used for looking up source information etc.
      */
-    public SearchableCorpora(Context context, Sources sources, CorpusFactory corpusFactory) {
+    public SearchableCorpora(Context context, SearchSettings settings, Sources sources,
+            CorpusFactory corpusFactory) {
         mContext = context;
+        mSettings = settings;
         mCorpusFactory = corpusFactory;
         mSources = sources;
     }
@@ -109,7 +113,7 @@
             for (Source source : corpus.getSources()) {
                 mCorporaBySource.put(source, corpus);
             }
-            if (corpus.isCorpusEnabled()) {
+            if (mSettings.isCorpusEnabled(corpus)) {
                 mEnabledCorpora.add(corpus);
             }
             if (corpus.isWebCorpus()) {
diff --git a/src/com/android/quicksearchbox/SearchableCorpusFactory.java b/src/com/android/quicksearchbox/SearchableCorpusFactory.java
index 6861d76..d3a8367 100644
--- a/src/com/android/quicksearchbox/SearchableCorpusFactory.java
+++ b/src/com/android/quicksearchbox/SearchableCorpusFactory.java
@@ -37,12 +37,15 @@
 
     private final Config mConfig;
 
+    private final SearchSettings mSettings;
+
     private final Factory<Executor> mWebCorpusExecutorFactory;
 
-    public SearchableCorpusFactory(Context context, Config config,
+    public SearchableCorpusFactory(Context context, Config config, SearchSettings settings,
             Factory<Executor> webCorpusExecutorFactory) {
         mContext = context;
         mConfig = config;
+        mSettings = settings;
         mWebCorpusExecutorFactory = webCorpusExecutorFactory;
     }
 
@@ -114,7 +117,7 @@
             browserSource = null;
         }
         Executor executor = createWebCorpusExecutor();
-        return new WebCorpus(mContext, mConfig, executor, webSource, browserSource);
+        return new WebCorpus(mContext, mConfig, mSettings, executor, webSource, browserSource);
     }
 
     protected Corpus createAppsCorpus(Sources sources) {
diff --git a/src/com/android/quicksearchbox/SearchableItemsSettings.java b/src/com/android/quicksearchbox/SearchableItemsSettings.java
index 0015a99..bded6f6 100644
--- a/src/com/android/quicksearchbox/SearchableItemsSettings.java
+++ b/src/com/android/quicksearchbox/SearchableItemsSettings.java
@@ -42,7 +42,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        getPreferenceManager().setSharedPreferencesName(SearchSettings.PREFERENCES_NAME);
+        getPreferenceManager().setSharedPreferencesName(SearchSettingsImpl.PREFERENCES_NAME);
 
         addPreferencesFromResource(R.xml.preferences_searchable_items);
 
@@ -52,6 +52,10 @@
         populateSourcePreference();
     }
 
+    private SearchSettings getSettings() {
+        return QsbApplication.get(this).getSettings();
+    }
+
     private Corpora getCorpora() {
         return QsbApplication.get(this).getCorpora();
     }
@@ -75,7 +79,7 @@
      */
     private Preference createCorpusPreference(Corpus corpus) {
         SearchableItemPreference sourcePref = new SearchableItemPreference(this);
-        sourcePref.setKey(SearchSettings.getCorpusEnabledPreference(corpus));
+        sourcePref.setKey(SearchSettingsImpl.getCorpusEnabledPreference(corpus));
         // Put web corpus first. The rest are alphabetical.
         if (corpus.isWebCorpus()) {
             sourcePref.setOrder(0);
@@ -92,7 +96,7 @@
     }
 
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        SearchSettings.broadcastSettingsChanged(this);
+        getSettings().broadcastSettingsChanged();
         return true;
     }
 
diff --git a/src/com/android/quicksearchbox/WebCorpus.java b/src/com/android/quicksearchbox/WebCorpus.java
index c3a872d..0f6f9db 100644
--- a/src/com/android/quicksearchbox/WebCorpus.java
+++ b/src/com/android/quicksearchbox/WebCorpus.java
@@ -41,20 +41,27 @@
 
     private static final String WEB_CORPUS_NAME = "web";
 
+    private final SearchSettings mSettings;
+
     private Source mWebSearchSource;
 
     private final Source mBrowserSource;
 
-    public WebCorpus(Context context, Config config, Executor executor,
+    public WebCorpus(Context context, Config config, SearchSettings settings, Executor executor,
             Source webSearchSource, Source browserSource) {
         super(context, config, executor, webSearchSource, browserSource);
         if (DBG) {
             Log.d(TAG, "init webSource=" + webSearchSource + "; browser source = " + browserSource);
         }
+        mSettings = settings;
         mWebSearchSource = webSearchSource;
         mBrowserSource = browserSource;
     }
 
+    protected SearchSettings getSettings() {
+        return mSettings;
+    }
+
     public void setWebSource(Source web) {
         if (DBG) Log.d(TAG, "setWebSource(" + web + ")");
         mWebSearchSource = web;
@@ -163,7 +170,7 @@
     @Override
     protected List<Source> getSourcesToQuery(String query, boolean onlyCorpus) {
         ArrayList<Source> sourcesToQuery = new ArrayList<Source>(2);
-        if (SearchSettings.getShowWebSuggestions(getContext())) {
+        if (getSettings().getShowWebSuggestions()) {
             if (mWebSearchSource != null) sourcesToQuery.add(mWebSearchSource);
         }
         if (mBrowserSource != null && query.length() > 0) {
diff --git a/src/com/android/quicksearchbox/google/GoogleSettings.java b/src/com/android/quicksearchbox/google/GoogleSettings.java
deleted file mode 100644
index 86b4c48..0000000
--- a/src/com/android/quicksearchbox/google/GoogleSettings.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quicksearchbox.google;
-
-import com.android.quicksearchbox.R;
-import com.android.quicksearchbox.SearchSettings;
-
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.preference.Preference.OnPreferenceClickListener;
-
-/**
- * Activity for setting Google search preferences.
- */
-public class GoogleSettings extends PreferenceActivity implements OnPreferenceClickListener {
-
-    private static final String SHOW_WEB_SUGGESTIONS_PREF = "show_web_suggestions";
-
-    private CheckBoxPreference mShowWebSuggestionsPreference;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.google_preferences);
-        mShowWebSuggestionsPreference = (CheckBoxPreference)
-                findPreference(SHOW_WEB_SUGGESTIONS_PREF);
-        mShowWebSuggestionsPreference.setOnPreferenceClickListener(this);
-        updateShowWebSuggestionsPreference();
-    }
-
-    /**
-     * Updates the "show web suggestions" preference from the value in system settings.
-     */
-    private void updateShowWebSuggestionsPreference() {
-        boolean showWebSuggestions = SearchSettings.getShowWebSuggestions(this);
-        mShowWebSuggestionsPreference.setChecked(showWebSuggestions);
-    }
-
-    /**
-     * Stores the "show web suggestions" preference to the system settings.
-     */
-    private void storeShowWebSuggestionsPreference() {
-        boolean showWebSuggestions = mShowWebSuggestionsPreference.isChecked();
-        SearchSettings.setShowWebSuggestions(this, showWebSuggestions);
-    }
-
-    public boolean onPreferenceClick(Preference preference) {
-        if (preference == mShowWebSuggestionsPreference) {
-            storeShowWebSuggestionsPreference();
-            return true;
-        }
-        return false;
-    }
-
-}
diff --git a/tests/src/com/android/quicksearchbox/MockSearchSettings.java b/tests/src/com/android/quicksearchbox/MockSearchSettings.java
new file mode 100644
index 0000000..145f91f
--- /dev/null
+++ b/tests/src/com/android/quicksearchbox/MockSearchSettings.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quicksearchbox;
+
+import android.content.Intent;
+import android.view.Menu;
+
+/**
+ * Mock implementation of {@link SearchSettings}.
+ */
+public class MockSearchSettings implements SearchSettings {
+
+    public void addMenuItems(Menu menu) {
+    }
+
+    public void broadcastSettingsChanged() {
+    }
+
+    public Intent getSearchableItemsIntent() {
+        return null;
+    }
+
+    public boolean getShowWebSuggestions() {
+        return true;
+    }
+
+    public boolean isCorpusEnabled(Corpus corpus) {
+        return true;
+    }
+
+    public void upgradeSettingsIfNeeded() {
+    }
+
+    public void resetVoiceSearchHintFirstSeenTime() {
+    }
+
+    public boolean haveVoiceSearchHintsExpired(int currentVoiceSearchVersion) {
+        return false;
+    }
+
+    public int getNextVoiceSearchHintIndex(int size) {
+        return 0;
+    }
+
+    public Intent getSearchSettingsIntent() {
+        return null;
+    }
+
+    public void updateMenuItems(Menu menu) {
+    }
+
+}
diff --git a/tests/src/com/android/quicksearchbox/SearchableCorporaTest.java b/tests/src/com/android/quicksearchbox/SearchableCorporaTest.java
index 3416eb4..b4c1d94 100644
--- a/tests/src/com/android/quicksearchbox/SearchableCorporaTest.java
+++ b/tests/src/com/android/quicksearchbox/SearchableCorporaTest.java
@@ -28,16 +28,19 @@
 @MediumTest
 public class SearchableCorporaTest extends AndroidTestCase {
 
+    protected SearchSettings mSettings;
+
     protected SearchableCorpora mCorpora;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
+        mSettings = new MockSearchSettings();
         MockSources sources = new MockSources();
         sources.addSource(MockSource.SOURCE_1);
         sources.addSource(MockSource.SOURCE_2);
-        mCorpora = new SearchableCorpora(mContext, sources, new MockCorpusFactory());
+        mCorpora = new SearchableCorpora(mContext, mSettings, sources, new MockCorpusFactory());
         mCorpora.update();
     }