Merge "Displays frequency on connected WiFi network info. Bug: 12767819"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cc1208e..deebc57 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -575,7 +575,7 @@
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.ZenModeSettings" />
             <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
-                android:resource="@id/sound_settings" />
+                android:resource="@id/notification_settings" />
         </activity>
 
         <activity android:name="Settings$DisplaySettingsActivity"
@@ -1708,6 +1708,24 @@
                        android:resource="@id/security_settings" />
         </activity>
 
+        <activity android:name="Settings$NotificationSettingsActivity"
+                android:label="@string/notification_settings"
+                android:exported="true"
+                android:taskAffinity=""
+                android:excludeFromRecents="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.settings.NOTIFICATION_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="com.android.settings.SHORTCUT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.NotificationSettings" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                android:resource="@id/notification_settings" />
+        </activity>
+
+
         <!-- Show regulatory info (from settings item or dialing "*#07#") -->
         <activity android:name="RegulatoryInfoDisplayActivity"
                   android:label="@string/regulatory_information"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..be2e221 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -44,6 +44,8 @@
 #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
 #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
 
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Settings_intermediates)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/res/drawable-hdpi/ic_settings_notifications.png b/res/drawable-hdpi/ic_settings_notifications.png
index aefb57b..5041ebb 100644
--- a/res/drawable-hdpi/ic_settings_notifications.png
+++ b/res/drawable-hdpi/ic_settings_notifications.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_settings_notifications.png b/res/drawable-mdpi/ic_settings_notifications.png
index fa7a07c..b8022fd 100644
--- a/res/drawable-mdpi/ic_settings_notifications.png
+++ b/res/drawable-mdpi/ic_settings_notifications.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_settings_notifications.png b/res/drawable-xhdpi/ic_settings_notifications.png
index c6c5c43..4a21a1b 100644
--- a/res/drawable-xhdpi/ic_settings_notifications.png
+++ b/res/drawable-xhdpi/ic_settings_notifications.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_settings_notifications.png b/res/drawable-xxhdpi/ic_settings_notifications.png
new file mode 100644
index 0000000..6f5d5c1
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_settings_notifications.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4451fce..4c2ea06 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -478,7 +478,7 @@
     <string name="bluetooth_device_context_connect_advanced" msgid="2643129703569788771">"Opsies…"</string>
     <string name="bluetooth_menu_advanced" msgid="8572178316357220524">"Gevorderd"</string>
     <string name="bluetooth_advanced_titlebar" msgid="2142159726881547669">"Gevorderde Bluetooth"</string>
-    <string name="bluetooth_empty_list_bluetooth_off" msgid="6351930724051893423">"Wanneer Bluetooth aangeskakel is, kan jou toestel met ander Bluetooth-toestelle wat naby is, kommunikeer."</string>
+    <string name="bluetooth_empty_list_bluetooth_off" msgid="6351930724051893423">"Wanneer Bluetooth aangeskakel is, kan jou toestel met ander nabygeleë Bluetooth-toestelle kommunikeer."</string>
     <string name="bluetooth_connect_specific_profiles_title" msgid="6952214406025825164">"Koppel aan…"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media-oudio"</string>
     <string name="bluetooth_profile_headset" msgid="8658779596261212609">"Foonoudio"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index b1ebdb8..7ac98c8 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -270,7 +270,7 @@
     <string name="sd_card_settings_label" product="nosdcard" msgid="8101475181301178428">"የUSB  ማከማቻ"</string>
     <string name="sd_card_settings_label" product="default" msgid="5743100901106177102">"SD ካርድ"</string>
     <string name="proxy_settings_label" msgid="3271174136184391743">"የእጅ አዙር ቅንብሮች"</string>
-    <string name="cancel" msgid="6859253417269739139">"ሰርዝ"</string>
+    <string name="cancel" msgid="6859253417269739139">"ይቅር"</string>
     <string name="settings_label" msgid="1626402585530130914">"ቅንብሮች"</string>
     <string name="settings_label_launcher" msgid="8344735489639482340">"ቅንብሮች"</string>
     <string name="settings_shortcut" msgid="3936651951364030415">"የቅንብሮች አቋራጭ"</string>
@@ -425,8 +425,8 @@
   </plurals>
     <string name="lockpassword_password_recently_used" msgid="6098087796784262081">"የቅርብ ጊዜ የይለፍ ቃል መጠቀም የመሳሪያ አስተዳዳሪ አይፈቅድም።"</string>
     <string name="lockpassword_ok_label" msgid="313822574062553672">"እሺ"</string>
-    <string name="lockpassword_cancel_label" msgid="8818529276331121899">"ሰርዝ"</string>
-    <string name="lockpattern_tutorial_cancel_label" msgid="6431583477570493261">"ሰርዝ"</string>
+    <string name="lockpassword_cancel_label" msgid="8818529276331121899">"ይቅር"</string>
+    <string name="lockpattern_tutorial_cancel_label" msgid="6431583477570493261">"ይቅር"</string>
     <string name="lockpattern_tutorial_continue_label" msgid="3559793618653400434">"ቀጥሎ"</string>
     <string name="lock_setup" msgid="3355847066343753943">"ማዋቀር ተጠናቋል።"</string>
     <string name="device_admin_title" msgid="3562216873644263804">"መሣሪያ አስተዳደር"</string>
@@ -457,7 +457,7 @@
     <string name="bluetooth_incoming_pairing_msg" msgid="1615930853859551491">"ከ:&lt;br&gt;&lt;b&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/b&gt;&lt;br&gt;&lt;br&gt;ከዚህ መሣሪያ ጋር ይጣመር?"</string>
     <string name="bluetooth_display_passkey_pin_msg" msgid="2796550001376088433">"ከ:<xliff:g id="BOLD1_0">&lt;br&gt;&lt;b&gt;</xliff:g><xliff:g id="DEVICE_NAME">%1$s</xliff:g><xliff:g id="END_BOLD1">&lt;/b&gt;&lt;br&gt;&lt;br&gt;</xliff:g> ጋር ለማጣመር ላዩ ላይ ተይብበት:<xliff:g id="BOLD2_1">&lt;br&gt;&lt;b&gt;</xliff:g><xliff:g id="PASSKEY">%2$s</xliff:g><xliff:g id="END_BOLD2">&lt;/b&gt;</xliff:g> ከዚያም ተመለስ ወይም አስገባ ተጫን::"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"አጣምር"</string>
-    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ሰርዝ"</string>
+    <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"ይቅር"</string>
     <string name="bluetooth_error_title" msgid="6850384073923533096"></string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"ከ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ማጣመር አልተቻለም::"</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ከ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ጋር ትክክለኛ ባልሆነ ፒን ወይም የይለፍቁልፍ ምክንያት ማጣመር አልተቻለም::"</string>
@@ -635,7 +635,7 @@
     <string name="wifi_failed_forget_message" msgid="1348172929201654986">"አውታረ መረብ መርሳት አልተሳካም"</string>
     <string name="wifi_save" msgid="3331121567988522826">"አስቀምጥ"</string>
     <string name="wifi_failed_save_message" msgid="6650004874143815692">"አውታረ መረብ ማስቀመጥ አልተሳካም"</string>
-    <string name="wifi_cancel" msgid="6763568902542968964">"ሰርዝ"</string>
+    <string name="wifi_cancel" msgid="6763568902542968964">"ይቅር"</string>
     <string name="wifi_skip_anyway" msgid="6965361454438011190">"ለማንኛውም ዝለለ"</string>
     <string name="wifi_dont_skip" msgid="7350341524881124808">"አትዝለል"</string>
     <string name="wifi_skipped_message" product="tablet" msgid="3335132188969450252">"ማስጠንቀቂያ፦ ተጨማሪ የድምጸ ሞደም ተያያዥ ውሂብ ክፍያዎች ሊከሰትብዎ ይችላል።\n\nጡባዊን ማዋቀር ጉልህ የሆነ የአውታረ መረብ እንቅስቃሴ ሊያስፈልገው ይችላል።"</string>
@@ -652,7 +652,7 @@
     <string name="wifi_advanced_ip_address_title" msgid="6215297094363164846">"IP አድራሻ"</string>
     <string name="wifi_advanced_settings_label" msgid="3654366894867838338">"IP ቅንብሮች"</string>
     <string name="wifi_ip_settings_menu_save" msgid="7296724066102908366">"አስቀምጥ"</string>
-    <string name="wifi_ip_settings_menu_cancel" msgid="6582567330136502340">"ሰርዝ"</string>
+    <string name="wifi_ip_settings_menu_cancel" msgid="6582567330136502340">"ይቅር"</string>
     <string name="wifi_ip_settings_invalid_ip_address" msgid="2513142355364274970">"እባክህ ትክክለኛ IP አድራሻ ተይብ።"</string>
     <string name="wifi_ip_settings_invalid_gateway" msgid="8164264988361096450">"እባክህ ትክክለኛ ኣግባቢ ፍኖት አድራሻ ተይብ።"</string>
     <string name="wifi_ip_settings_invalid_dns" msgid="8744583948328391047">"እባክህ ትክክለኛ dns አድራሻ ተይብ።"</string>
@@ -674,8 +674,8 @@
     <string name="wifi_p2p_disconnect_title" msgid="3216846049677448420">"ይላቀቅ?"</string>
     <string name="wifi_p2p_disconnect_message" msgid="8227342771610125771">"ግንኙነቱን ካቋረጥክ፣ ከ<xliff:g id="PEER_NAME">%1$s</xliff:g> ጋር ያለህ ግንኙነት ይቋረጣል።"</string>
     <string name="wifi_p2p_disconnect_multiple_message" msgid="3283805371034883105">"ግንኙነቱን ካቋረጥክ፣ ከ<xliff:g id="PEER_NAME">%1$s</xliff:g> እና <xliff:g id="PEER_COUNT">%2$s</xliff:g> ሌላ መሳሪያዎች ጋር ያለህ ግንኙነት ይቋረጣል።"</string>
-    <string name="wifi_p2p_cancel_connect_title" msgid="255267538099324413">"ግብዣ ይሰረዝ?"</string>
-    <string name="wifi_p2p_cancel_connect_message" msgid="7477756213423749402">"ከ<xliff:g id="PEER_NAME">%1$s</xliff:g> ጋር የመገናኘት ግብዣውን መሰረዝ ይፈልጋሉ?"</string>
+    <string name="wifi_p2p_cancel_connect_title" msgid="255267538099324413">"ግብዣ ይቅር?"</string>
+    <string name="wifi_p2p_cancel_connect_message" msgid="7477756213423749402">"ከ<xliff:g id="PEER_NAME">%1$s</xliff:g> ጋር የመገናኘት ግብዣውን ይቅር ማለት ይፈልጋሉ?"</string>
     <string name="wifi_p2p_delete_group_message" msgid="834559380069647086">"ይህ ቡድን ይረሳ?"</string>
     <string name="wifi_tether_checkbox_text" msgid="1847167643625779136">"ተንቀሳቃሽ የWi-Fi መገናኛ ነጥብ"</string>
     <string name="wifi_tether_starting" msgid="1322237938998639724">"የመገናኛ ነጥብን በማብራት ላይ…"</string>
@@ -786,7 +786,7 @@
     <string name="sim_change_succeeded" msgid="8556135413096489627">"SIM ፒን  በተሳካ ተለውጧል"</string>
     <string name="sim_lock_failed" msgid="5651596916127873626">"የሲም ካርድን ቆልፍ ሁኔታ ለመለወጥ አይቻልም። \n የተሳሳተ ፒን ሊሆን ይችላል።"</string>
     <string name="sim_enter_ok" msgid="6475946836899218919">"እሺ"</string>
-    <string name="sim_enter_cancel" msgid="6240422158517208036">"ሰርዝ"</string>
+    <string name="sim_enter_cancel" msgid="6240422158517208036">"ይቅር"</string>
     <string name="wrong_pin_code_pukked" msgid="4003655226832658066">"ልክ ያልሆነ የሲም ኮድ። አሁን መሳሪያዎን ለማስከፈት ድምጸ ተያያዥ ሞደምዎን ማግኘት አለብዎ።"</string>
   <plurals name="wrong_pin_code">
     <item quantity="one" msgid="4840607930166101114">"ልክ ያልሆነ የሲም ፒን ኮድ፣ መሳሪያዎን ለማስከፈት ድምጸ ተያያዥ ሞደምዎን ማግኘት ግዴታዎ ሊሆን <xliff:g id="NUMBER">%d</xliff:g> ሙከራ ይቀርዎታል።"</item>
@@ -1159,7 +1159,7 @@
     <string name="clear_data_dlg_title" msgid="5605258400134511197">"መተግበሪያ ውሂብ ሰርዝ?"</string>
     <string name="clear_data_dlg_text" msgid="8847257251846779938">"የዚህ መተግበሪያ ውሂቦች ሁሉ በቋሚነት ይሰረዛሉ።እነዚህም ፋይሎችን፣ ቅንብሮችን፣ መለያዎችን፣ የውሂብ ጎታዎች እና የመሳሰሉትን ያካትታሉ።"</string>
     <string name="dlg_ok" msgid="2402639055725653590">"እሺ"</string>
-    <string name="dlg_cancel" msgid="1674753358972975911">"ሰርዝ"</string>
+    <string name="dlg_cancel" msgid="1674753358972975911">"ይቅር"</string>
     <string name="app_not_found_dlg_title" msgid="3127123411738434964"></string>
     <string name="app_not_found_dlg_text" msgid="8333723538280257243">"መተግበሪያው በተጫኑ ትግበራዎች ዝርዝር ውስጥ አልተገኘም።"</string>
     <string name="clear_data_failed" msgid="1907582169616856698">"የመተግበሪያ ውሂብ ማጽዳት አልተቻለም::"</string>
@@ -1304,7 +1304,7 @@
     <string name="quick_launch_clear_dialog_title" msgid="5546543501250320220">"አጥራ"</string>
     <string name="quick_launch_clear_dialog_message" msgid="3921015601470260722">"የ<xliff:g id="SHORTCUT_LETTER">%1$s</xliff:g> (<xliff:g id="APPLICATION_NAME">%2$s</xliff:g>) አቋራጭዎ ይጠራል።"</string>
     <string name="quick_launch_clear_ok_button" msgid="2634568926597586716">"እሺ"</string>
-    <string name="quick_launch_clear_cancel_button" msgid="1892854652197747064">"ሰርዝ"</string>
+    <string name="quick_launch_clear_cancel_button" msgid="1892854652197747064">"ይቅር"</string>
     <string name="quick_launch_display_mode_applications" msgid="1734058461846126775">"መተግበሪያዎች"</string>
     <string name="quick_launch_display_mode_shortcuts" msgid="4177934019174169042">"አቋራጮች"</string>
     <string name="input_methods_settings_title" msgid="6800066636850553887">"ፅሁፍ ግቤት"</string>
@@ -1472,7 +1472,7 @@
     <string name="print_print_jobs" msgid="3582094777756968793">"የህትመት ስራዎች"</string>
     <string name="print_print_job" msgid="7563741676053287211">"የህትመት ስራ"</string>
     <string name="print_restart" msgid="8373999687329384202">"እንደገና ጀምር"</string>
-    <string name="print_cancel" msgid="3621199386568672235">"ሰርዝ"</string>
+    <string name="print_cancel" msgid="3621199386568672235">"ይቅር"</string>
     <string name="print_job_summary" msgid="8472427347192930694">"<xliff:g id="PRINTER">%1$s</xliff:g>\n<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="print_printing_state_title_template" msgid="5736107667714582025">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በማተም ላይ"</string>
     <string name="print_cancelling_state_title_template" msgid="7102968925358219875">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በመተው ላይ"</string>
@@ -1738,7 +1738,7 @@
     <string name="wifi_setup_connect" msgid="7954456989590237049">"አያይዝ"</string>
     <string name="wifi_setup_forget" msgid="2562847595567347526">"እርሳ"</string>
     <string name="wifi_setup_save" msgid="3659235094218508211">"አስቀምጥ"</string>
-    <string name="wifi_setup_cancel" msgid="3185216020264410239">"ሰርዝ"</string>
+    <string name="wifi_setup_cancel" msgid="3185216020264410239">"ይቅር"</string>
     <string name="wifi_setup_status_scanning" msgid="5317003416385428036">"አውታረ መረቦች በመቃኘት ላይ....."</string>
     <string name="wifi_setup_status_select_network" msgid="7519563569903137003">"አውታረ መረብ ለመያያዝ ንካ"</string>
     <string name="wifi_setup_status_existing_network" msgid="6394925174802598186">"ካለው አውታረ መረብ ጋር አያይዝ"</string>
@@ -1772,7 +1772,7 @@
     <string name="settings_backup" msgid="2274732978260797031">"ቅንብሮች  ተተኪ አኑር"</string>
     <string name="settings_backup_summary" msgid="7916877705938054035">"ቅንብሮቼን ተተኪ አኑር"</string>
     <string name="sync_menu_sync_now" msgid="6154608350395805683">"አሁን አስምር"</string>
-    <string name="sync_menu_sync_cancel" msgid="8292379009626966949">"ሥምሪያ ሰርዝ"</string>
+    <string name="sync_menu_sync_cancel" msgid="8292379009626966949">"ሥምሪያ ይቅር"</string>
     <string name="sync_one_time_sync" msgid="6766593624598183090">"<xliff:g id="LAST_SYNC_TIME">
 %1$s</xliff:g> አሁን ለማስመር ንካ"</string>
     <string name="sync_gmail" msgid="714886122098006477">"Gmail"</string>
@@ -1947,7 +1947,7 @@
     <string name="vpn_not_used" msgid="9094191054524660891">"(አላገለገለም)"</string>
     <string name="vpn_no_ca_cert" msgid="2095005387500126113">"(አገልጋይ አታረጋግጥ)"</string>
     <string name="vpn_no_server_cert" msgid="2167487440231913330">"(ከአገልጋይ የደረሰ)"</string>
-    <string name="vpn_cancel" msgid="1979937976123659332">"ሰርዝ"</string>
+    <string name="vpn_cancel" msgid="1979937976123659332">"ይቅር"</string>
     <string name="vpn_save" msgid="4233484051644764510">"አስቀምጥ"</string>
     <string name="vpn_connect" msgid="8469608541746132301">"አያይዝ"</string>
     <string name="vpn_edit" msgid="8647191407179996943">"የVPN መገለጫ አርትዑ"</string>
@@ -1975,7 +1975,7 @@
     <string name="new_backup_pw_prompt" msgid="8755501377391998428">"ለሙሉ መጠባበቂያ አዲስ የይለፍ ቃል እዚህ አስገባ"</string>
     <string name="confirm_new_backup_pw_prompt" msgid="3238728882512787864">"ሙሉ የይለፍቃል ምትኬህን እዚህ ዳግም ተይብ።"</string>
     <string name="backup_pw_set_button_text" msgid="2387480910044648795">"የመጠባበቂያ ይለፍቃል አዘጋጅ"</string>
-    <string name="backup_pw_cancel_button_text" msgid="8845630125391744615">"ሰርዝ"</string>
+    <string name="backup_pw_cancel_button_text" msgid="8845630125391744615">"ይቅር"</string>
     <string name="percentage" msgid="5866131581207788624">"+<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="additional_system_update_settings_list_item_title" msgid="214987609894661992">"ተጨማሪ የስርዓት አዘምኖች"</string>
     <string name="selinux_status_disabled" msgid="924551035552323327">"ተሰናክሏል"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 882ae55..1d6c751 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2399,7 +2399,7 @@
     <!-- SMS Application [CHAR LIMIT=35]-->
     <string name="sms_application_title" translatable="true">Default SMS app</string>
     <string name="sms_change_default_dialog_title" translatable="true">Change SMS app?</string>
-    <string name="sms_change_default_dialog_text" translatable="true">Use <xliff:g id="new_app">%s</xliff:g> instead of <xliff:g id="current_app">%s</xliff:g> as your SMS app?</string>
+    <string name="sms_change_default_dialog_text" translatable="true">Use <xliff:g id="new_app">%1$s</xliff:g> instead of <xliff:g id="current_app">%2$s</xliff:g> as your SMS app?</string>
     <string name="sms_change_default_no_previous_dialog_text" translatable="true">Use <xliff:g id="new_app">%s</xliff:g> as your SMS app?</string>
 
     <!-- The SIM operator is not known [CHAR_ LIMIT=50]-->
@@ -3608,7 +3608,7 @@
     <!-- Label for power consumed when Idle -->
     <string name="power_idle" product="default">Phone idle</string>
     <!-- Label for power that we aren't able to account for -->
-    <string name="power_unaccounted">Unknown</string>
+    <string name="power_unaccounted">Miscellaneous</string>
     <!-- Label for power that we computed too much for -->
     <string name="power_overcounted">Over-counted</string>
 
@@ -5008,25 +5008,37 @@
 
     <!-- Notifications on lockscreen -->
     <!-- Label for checkbox controlling the contents of notifications shown on
-         the secure lockscreen [CHAR LIMIT=16] -->
-    <string name="lock_screen_notifications">Show notifications</string>
+         the secure lockscreen [CHAR LIMIT=25] -->
+    <string name="lock_screen_notifications">Show when locked</string>
     <!-- Summary for lock_screen_notifications: sensitive information will be
          hidden or redacted from notifications shown on a secure lock screen
          [CHAR LIMIT=50] -->
-    <string name="lock_screen_notifications_summary_off">Sensitive notification contents will be hidden when locked</string>
+    <string name="lock_screen_notifications_summary_off">Sensitive notification contents will be hidden on the lock screen</string>
     <!-- Summary for lock_screen_notifications: all information will be
          shown in notifications shown on a secure lock screen
          [CHAR LIMIT=50] -->
-    <string name="lock_screen_notifications_summary_on">All notification contents will be shown when locked</string>
+    <string name="lock_screen_notifications_summary_on">All notification contents will be shown on the lock screen</string>
 
     <!-- [CHAR LIMIT=30] Sound settings screen, setting option name to change zen mode -->
-    <string name="title_zen_mode">Zen mode</string>
-    <!-- [CHAR LIMIT=30] Sound settings screen, setting option summary displaying the currently selected zen mode -->
-    <string name="summary_zen_mode" translatable="false">%1$s</string>
-    <!-- [CHAR LIMIT=40] Sound settings screen, title of dialog for picking zen mode -->
-    <string name="dialog_title_zen_mode">Zen mode</string>
+    <string name="title_zen_mode">Limited interruptions</string>
     <!-- [CHAR LIMIT=30] Sound settings screen, description for configuring zen mode -->
-    <string name="configure_zen_mode_description">Configure Zen mode</string>
+    <string name="configure_zen_mode_description">Configure limited interruptions</string>
     <!-- [CHAR LIMIT=30] Zen mode settings screen, activity title -->
     <string name="zen_mode_settings_title">Limited Interruptions</string>
+
+    <!-- [CHAR LIMIT=20] Notifications settings header -->
+    <string name="notification_settings">Notifications</string>
+
+    <!-- [CHAR LIMIT=20] Notifications settings: General section header -->
+    <string name="notification_settings_general">General</string>
+
+    <!-- [CHAR LIMIT=20] Notifications settings: Security section header -->
+    <string name="notification_settings_security">Security</string>
+
+    <!-- [CHAR LIMIT=20] Notifications settings: Tweaks section header (eng
+         builds only) -->
+    <string name="notification_settings_tweaks">Tweaks</string>
+
+    <!-- [CHAR LIMIT=20] Notifications settings: Apps section header -->
+    <string name="notification_settings_apps">Apps</string>
 </resources>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 53d9915..67cd7d3 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -48,17 +48,6 @@
                 android:entryValues="@array/entryvalues_font_size"
                 android:dialogTitle="@string/dialog_title_font_size" />
 
-        <CheckBoxPreference
-            android:key="notification_pulse"
-            android:title="@string/notification_pulse_title"
-            android:persistent="false" />
-
-        <CheckBoxPreference
-            android:key="heads_up"
-            android:title="@string/heads_up_enabled_title"
-            android:summary="@string/heads_up_enabled_summary"
-            android:persistent="false" />
-
         <PreferenceScreen
                 android:key="wifi_display"
                 android:title="@string/wifi_display_settings_title"
diff --git a/res/xml/notification_settings.xml b/res/xml/notification_settings.xml
new file mode 100644
index 0000000..edea08f
--- /dev/null
+++ b/res/xml/notification_settings.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        android:title="@string/notification_settings"
+        android:key="notification_settings"
+        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
+
+    <PreferenceCategory
+            android:key="category_general"
+            android:title="@string/notification_settings_general">
+
+        <com.android.settings.DefaultRingtonePreference
+                android:key="notification_sound"
+                android:title="@string/notification_sound_title"
+                android:dialogTitle="@string/notification_sound_dialog_title"
+                android:persistent="false"
+                android:ringtoneType="notification" />
+
+        <CheckBoxPreference
+                android:key="notification_pulse"
+                android:title="@string/notification_pulse_title"
+                android:persistent="false" />
+
+        <CheckBoxPreference
+                android:key="heads_up"
+                android:title="@string/heads_up_enabled_title"
+                android:summary="@string/heads_up_enabled_summary"
+                android:persistent="false" />
+
+        <PreferenceScreen
+                android:key="zen_mode"
+                android:title="@string/title_zen_mode"
+                android:fragment="com.android.settings.ZenModeSettings" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:key="category_security"
+            android:title="@string/notification_settings_security">
+
+        <CheckBoxPreference
+                android:key="toggle_lock_screen_notifications"
+                android:title="@string/lock_screen_notifications"
+                android:summaryOff="@string/lock_screen_notifications_summary_off"
+                android:summaryOn="@string/lock_screen_notifications_summary_on"
+                android:persistent="false" />
+
+        <Preference
+                android:key="manage_notification_access"
+                android:title="@string/manage_notification_access"
+                android:persistent="false"
+                android:fragment="com.android.settings.NotificationAccessSettings"/>
+
+    </PreferenceCategory>
+
+<!--
+    <PreferenceCategory
+            android:key="category_tweaks"
+            android:title="@string/notification_settings_tweaks"/>
+
+    <Preference
+            android:title="Coming soon"
+            />
+
+    <PreferenceCategory
+            android:key="category_apps"
+            android:title="@string/notification_settings_apps"/>
+
+    <Preference
+            android:title="Coming soon"
+            />
+-->
+
+</PreferenceScreen>
diff --git a/res/xml/security_settings_biometric_weak.xml b/res/xml/security_settings_biometric_weak.xml
index d994922..c2e8ab7 100644
--- a/res/xml/security_settings_biometric_weak.xml
+++ b/res/xml/security_settings_biometric_weak.xml
@@ -66,13 +66,6 @@
             android:title="@string/nfc_unlock_title"
             android:persistent="false"/>
 
-        <CheckBoxPreference
-            android:key="toggle_lock_screen_notifications"
-            android:title="@string/lock_screen_notifications"
-            android:summaryOff="@string/lock_screen_notifications_summary_off"
-            android:summaryOn="@string/lock_screen_notifications_summary_on"
-            android:persistent="false" />
-
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index 21cf88f..299bdf6 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -59,12 +59,6 @@
                 android:summaryOn="@string/verify_applications_summary"
                 android:persistent="false" />
 
-        <Preference
-                android:key="manage_notification_access"
-                android:title="@string/manage_notification_access"
-                android:persistent="false"
-                android:fragment="com.android.settings.NotificationAccessSettings"/>
-
     </PreferenceCategory>
 
     <PreferenceCategory android:key="credentials_management"
diff --git a/res/xml/security_settings_password.xml b/res/xml/security_settings_password.xml
index 20d7644..a102efa 100644
--- a/res/xml/security_settings_password.xml
+++ b/res/xml/security_settings_password.xml
@@ -53,13 +53,6 @@
             android:title="@string/nfc_unlock_title"
             android:persistent="false"/>
 
-        <CheckBoxPreference
-            android:key="toggle_lock_screen_notifications"
-            android:title="@string/lock_screen_notifications"
-            android:summaryOff="@string/lock_screen_notifications_summary_off"
-            android:summaryOn="@string/lock_screen_notifications_summary_on"
-            android:persistent="false" />
-
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/security_settings_pattern.xml b/res/xml/security_settings_pattern.xml
index c02df7a..0584e4a 100644
--- a/res/xml/security_settings_pattern.xml
+++ b/res/xml/security_settings_pattern.xml
@@ -57,13 +57,6 @@
             android:title="@string/nfc_unlock_title"
             android:persistent="false"/>
 
-        <CheckBoxPreference
-            android:key="toggle_lock_screen_notifications"
-            android:title="@string/lock_screen_notifications"
-            android:summaryOff="@string/lock_screen_notifications_summary_off"
-            android:summaryOn="@string/lock_screen_notifications_summary_on"
-            android:persistent="false" />
-
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/security_settings_pin.xml b/res/xml/security_settings_pin.xml
index 2636fa4..1417e21 100644
--- a/res/xml/security_settings_pin.xml
+++ b/res/xml/security_settings_pin.xml
@@ -53,13 +53,6 @@
             android:title="@string/nfc_unlock_title"
             android:persistent="false"/>
 
-        <CheckBoxPreference
-            android:key="toggle_lock_screen_notifications"
-            android:title="@string/lock_screen_notifications"
-            android:summaryOff="@string/lock_screen_notifications_summary_off"
-            android:summaryOn="@string/lock_screen_notifications_summary_on"
-            android:persistent="false" />
-
     </PreferenceCategory>
 
 </PreferenceScreen>
diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml
index 19cff90..c4b5eac 100644
--- a/res/xml/settings_headers.xml
+++ b/res/xml/settings_headers.xml
@@ -89,6 +89,13 @@
         android:fragment="com.android.settings.DisplaySettings"
         android:title="@string/display_settings" />
 
+    <!-- Notifications -->
+    <header
+        android:id="@+id/notification_settings"
+        android:icon="@drawable/ic_settings_notifications"
+        android:fragment="com.android.settings.NotificationSettings"
+        android:title="@string/notification_settings" />
+
     <!-- Storage -->
     <header
         android:id="@+id/storage_settings"
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 580b6d5..26e2e20 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -109,13 +109,4 @@
         android:title="@string/dock_sounds_enable_title"
         android:defaultValue="false" />
 
-    <com.android.settings.ZenModeListPreference
-            android:key="zen_mode"
-            android:persistent="false"
-            android:title="@string/title_zen_mode"
-            android:summary="@string/summary_zen_mode"
-            android:entries="@array/entries_zen_mode"
-            android:entryValues="@array/entryvalues_zen_mode"
-            android:dialogTitle="@string/dialog_title_zen_mode" />
-
 </PreferenceScreen>
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index d974d00..de7b05a 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -599,11 +599,13 @@
         }
         // Asynchronously throw up the IME, since there are issues with requesting it to be shown
         // immediately.
-        mHandler.postDelayed(new Runnable() {
-            @Override public void run() {
-                imm.showSoftInputUnchecked(0, null);
-            }
-        }, 0);
+        if (mLockPatternView == null) {
+            mHandler.postDelayed(new Runnable() {
+                @Override public void run() {
+                    imm.showSoftInputUnchecked(0, null);
+                }
+            }, 0);
+        }
 
         updateEmergencyCallButtonState();
         // Notify the user in 120 seconds that we are waiting for him to enter the password.
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index efd4705..afe5b68 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -49,21 +49,17 @@
 
     private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
     private static final String KEY_FONT_SIZE = "font_size";
-    private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
-    private static final String KEY_HEADS_UP = "heads_up";
     private static final String KEY_SCREEN_SAVER = "screensaver";
 
     private static final int DLG_GLOBAL_CHANGE_WARNING = 1;
 
     private WarnedListPreference mFontSizePref;
-    private CheckBoxPreference mNotificationPulse;
 
     private final Configuration mCurConfig = new Configuration();
     private final Handler mHandler = new Handler();
 
     private ListPreference mScreenTimeoutPreference;
     private Preference mScreenSaverPreference;
-    private CheckBoxPreference mHeadsUp;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -90,33 +86,6 @@
         mFontSizePref = (WarnedListPreference) findPreference(KEY_FONT_SIZE);
         mFontSizePref.setOnPreferenceChangeListener(this);
         mFontSizePref.setOnPreferenceClickListener(this);
-        mNotificationPulse = (CheckBoxPreference) findPreference(KEY_NOTIFICATION_PULSE);
-        if (mNotificationPulse != null
-                && getResources().getBoolean(
-                        com.android.internal.R.bool.config_intrusiveNotificationLed) == false) {
-            getPreferenceScreen().removePreference(mNotificationPulse);
-        } else {
-            try {
-                mNotificationPulse.setChecked(Settings.System.getInt(resolver,
-                        Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
-                mNotificationPulse.setOnPreferenceChangeListener(this);
-            } catch (SettingNotFoundException snfe) {
-                Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
-            }
-        }
-        mHeadsUp = (CheckBoxPreference) findPreference(KEY_HEADS_UP);
-        if (mHeadsUp != null) {
-            updateHeadsUpMode(resolver);
-            mHeadsUp.setOnPreferenceChangeListener(this);
-            resolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
-                    false, new ContentObserver(mHandler) {
-                @Override
-                public void onChange(boolean selfChange) {
-                    updateHeadsUpMode(resolver);
-                }
-            });
-        }
     }
 
     private void updateTimeoutPreferenceDescription(long currentTimeout) {
@@ -250,16 +219,6 @@
         }
     }
 
-    private void updateHeadsUpMode(ContentResolver resolver) {
-        mHeadsUp.setChecked(Settings.Global.HEADS_UP_ON == Settings.Global.getInt(resolver,
-                Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HEADS_UP_OFF));
-    }
-
-    private void setHeadsUpMode(ContentResolver resolver, boolean value) {
-        Settings.Global.putInt(resolver, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
-                value ? Settings.Global.HEADS_UP_ON : Settings.Global.HEADS_UP_OFF);
-    }
-
     public void writeFontSizePreference(Object objValue) {
         try {
             mCurConfig.fontScale = Float.parseFloat(objValue.toString());
@@ -271,18 +230,6 @@
 
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (preference == mNotificationPulse) {
-            boolean value = mNotificationPulse.isChecked();
-            Settings.System.putInt(getContentResolver(), Settings.System.NOTIFICATION_LIGHT_PULSE,
-                    value ? 1 : 0);
-            return true;
-        }
-        if (preference == mHeadsUp) {
-            final boolean value = mHeadsUp.isChecked();
-            Log.d(TAG, "onPreferenceTreeClick mHeadsUp: " + value);
-            setHeadsUpMode(getContentResolver(), value);
-            return true;
-        }
         return super.onPreferenceTreeClick(preferenceScreen, preference);
     }
 
diff --git a/src/com/android/settings/NotificationSettings.java b/src/com/android/settings/NotificationSettings.java
new file mode 100644
index 0000000..c8ba39a
--- /dev/null
+++ b/src/com/android/settings/NotificationSettings.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2014 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.settings;
+
+import android.content.ContentResolver;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.media.RingtoneManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.util.Log;
+
+public class NotificationSettings extends SettingsPreferenceFragment implements
+        Preference.OnPreferenceChangeListener, OnPreferenceClickListener {
+    private static final String TAG = "NotificationSettings";
+
+    private static final String KEY_NOTIFICATION_SOUND = "notification_sound";
+    private static final String KEY_ZEN_MODE = "zen_mode";
+    private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
+    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "toggle_lock_screen_notifications";
+    private static final String KEY_HEADS_UP = "heads_up";
+    private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
+
+    private static final String KEY_SECURITY_CATEGORY = "category_security";
+    private static final String KEY_TWEAKS_CATEGORY = "category_tweaks"; // power toys, eng only
+
+    private static final int MSG_UPDATE_SOUND_SUMMARY = 2;
+
+    private PackageManager mPM;
+
+    private Preference mNotificationSoundPreference;
+    private Preference mNotificationAccess;
+    private CheckBoxPreference mLockscreenNotifications;
+    private CheckBoxPreference mHeadsUp;
+    private CheckBoxPreference mNotificationPulse;
+
+    private final Runnable mRingtoneLookupRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mNotificationSoundPreference != null) {
+                final CharSequence summary = SoundSettings.updateRingtoneName(
+                        getActivity(), RingtoneManager.TYPE_NOTIFICATION);
+                if (summary != null) {
+                    mHandler.sendMessage(
+                            mHandler.obtainMessage(MSG_UPDATE_SOUND_SUMMARY, summary));
+                }
+            }
+        }
+    };
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_SOUND_SUMMARY:
+                    mNotificationSoundPreference.setSummary((CharSequence) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final ContentResolver resolver = getActivity().getContentResolver();
+
+        mPM = getActivity().getPackageManager();
+
+        addPreferencesFromResource(R.xml.notification_settings);
+
+        final PreferenceScreen root = getPreferenceScreen();
+        final PreferenceGroup securityCategory = (PreferenceGroup)
+                root.findPreference(KEY_SECURITY_CATEGORY);
+
+        PreferenceGroup tweaksCategory = (PreferenceGroup)
+                root.findPreference(KEY_TWEAKS_CATEGORY);
+
+        if (tweaksCategory != null
+                && !(Build.TYPE.equals("eng") || Build.TYPE.equals("userdebug"))) {
+            root.removePreference(tweaksCategory);
+            tweaksCategory = null;
+        }
+
+        mNotificationSoundPreference = findPreference(KEY_NOTIFICATION_SOUND);
+
+        mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS);
+        refreshNotificationListeners();
+
+        mLockscreenNotifications
+                = (CheckBoxPreference) root.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS);
+        if (mLockscreenNotifications != null) {
+            if (!getDeviceLockscreenNotificationsEnabled()) {
+                if (securityCategory != null) {
+                    securityCategory.removePreference(mLockscreenNotifications);
+                }
+            } else {
+                mLockscreenNotifications.setChecked(getLockscreenAllowPrivateNotifications());
+            }
+        }
+
+        mHeadsUp = (CheckBoxPreference) findPreference(KEY_HEADS_UP);
+        if (mHeadsUp != null) {
+            updateHeadsUpMode(resolver);
+            mHeadsUp.setOnPreferenceChangeListener(this);
+            resolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
+                    false, new ContentObserver(mHandler) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    updateHeadsUpMode(resolver);
+                }
+            });
+        }
+        mNotificationPulse = (CheckBoxPreference) findPreference(KEY_NOTIFICATION_PULSE);
+
+        if (mNotificationPulse != null
+                && getResources().getBoolean(
+                com.android.internal.R.bool.config_intrusiveNotificationLed) == false) {
+            getPreferenceScreen().removePreference(mNotificationPulse);
+        } else {
+            try {
+                mNotificationPulse.setChecked(Settings.System.getInt(resolver,
+                        Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
+                mNotificationPulse.setOnPreferenceChangeListener(this);
+            } catch (Settings.SettingNotFoundException snfe) {
+                Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
+            }
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        refreshNotificationListeners();
+        lookupRingtoneNames();
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        final String key = preference.getKey();
+
+        if (KEY_LOCK_SCREEN_NOTIFICATIONS.equals(key)) {
+            Settings.Secure.putInt(getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    mLockscreenNotifications.isChecked() ? 1 : 0);
+        } else if (KEY_HEADS_UP.equals(key)) {
+            setHeadsUpMode(getContentResolver(), mHeadsUp.isChecked());
+        } else if (KEY_NOTIFICATION_PULSE.equals(key)) {
+            Settings.System.putInt(getContentResolver(),
+                    Settings.System.NOTIFICATION_LIGHT_PULSE,
+                    mNotificationPulse.isChecked() ? 1 : 0);
+        } else {
+            return super.onPreferenceTreeClick(preferenceScreen, preference);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        return true;
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        return false;
+    }
+
+    // === Heads-up notifications ===
+
+    private void updateHeadsUpMode(ContentResolver resolver) {
+        mHeadsUp.setChecked(Settings.Global.HEADS_UP_ON == Settings.Global.getInt(resolver,
+                Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HEADS_UP_OFF));
+    }
+
+    private void setHeadsUpMode(ContentResolver resolver, boolean value) {
+        Settings.Global.putInt(resolver, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                value ? Settings.Global.HEADS_UP_ON : Settings.Global.HEADS_UP_OFF);
+    }
+
+    // === Lockscreen (public / private) notifications ===
+
+    private boolean getDeviceLockscreenNotificationsEnabled() {
+        return 0 != Settings.Global.getInt(getContentResolver(),
+                Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
+    }
+
+    private boolean getLockscreenAllowPrivateNotifications() {
+        return 0 != Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+    }
+
+    // === Notification listeners ===
+
+    private int getNumEnabledNotificationListeners() {
+        final String flat = Settings.Secure.getString(getContentResolver(),
+                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+        if (flat == null || "".equals(flat)) return 0;
+        final String[] components = flat.split(":");
+        return components.length;
+    }
+
+    private void refreshNotificationListeners() {
+        if (mNotificationAccess != null) {
+            final PreferenceGroup securityCategory
+                    = (PreferenceGroup) getPreferenceScreen().findPreference(KEY_SECURITY_CATEGORY);
+
+            final int total = NotificationAccessSettings.getListenersCount(mPM);
+            if (total == 0) {
+                if (securityCategory != null) {
+                    securityCategory.removePreference(mNotificationAccess);
+                }
+            } else {
+                final int n = getNumEnabledNotificationListeners();
+                if (n == 0) {
+                    mNotificationAccess.setSummary(getResources().getString(
+                            R.string.manage_notification_access_summary_zero));
+                } else {
+                    mNotificationAccess.setSummary(String.format(getResources().getQuantityString(
+                            R.plurals.manage_notification_access_summary_nonzero,
+                            n, n)));
+                }
+            }
+        }
+    }
+
+    // === Ringtone ===
+
+    private void lookupRingtoneNames() {
+        new Thread(mRingtoneLookupRunnable).start();
+    }
+}
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 84a07f2..c4f0c7f 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -84,8 +84,6 @@
     private static final String KEY_TOGGLE_VERIFY_APPLICATIONS = "toggle_verify_applications";
     private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
     private static final String KEY_CREDENTIALS_MANAGER = "credentials_management";
-    private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
-    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "toggle_lock_screen_notifications";
     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
 
     private PackageManager mPM;
@@ -109,9 +107,6 @@
     private CheckBoxPreference mPowerButtonInstantlyLocks;
     private CheckBoxPreference mEnableKeyguardWidgets;
 
-    private Preference mNotificationAccess;
-    private CheckBoxPreference mLockscreenNotifications;
-
     private boolean mIsPrimary;
 
     public SecuritySettings() {
@@ -330,26 +325,6 @@
             }
         }
 
-        mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS);
-        if (mNotificationAccess != null) {
-            final int total = NotificationAccessSettings.getListenersCount(mPM);
-            if (total == 0) {
-                if (deviceAdminCategory != null) {
-                    deviceAdminCategory.removePreference(mNotificationAccess);
-                }
-            } else {
-                final int n = getNumEnabledNotificationListeners();
-                if (n == 0) {
-                    mNotificationAccess.setSummary(getResources().getString(
-                            R.string.manage_notification_access_summary_zero));
-                } else {
-                    mNotificationAccess.setSummary(String.format(getResources().getQuantityString(
-                            R.plurals.manage_notification_access_summary_nonzero,
-                            n, n)));
-                }
-            }
-        }
-
         if (shouldBePinProtected(RESTRICTIONS_PIN_SET)) {
             protectByRestrictions(mToggleAppInstallation);
             protectByRestrictions(mToggleVerifyApps);
@@ -357,41 +332,9 @@
             protectByRestrictions(root.findPreference(KEY_CREDENTIALS_INSTALL));
         }
 
-        mLockscreenNotifications
-                = (CheckBoxPreference) root.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS);
-        if (mLockscreenNotifications != null) {
-            if (!getDeviceLockscreenNotificationsEnabled()) {
-                final PreferenceGroup lockscreenCategory =
-                        (PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY);
-                if (lockscreenCategory != null) {
-                    lockscreenCategory.removePreference(mLockscreenNotifications);
-                }
-            } else {
-                mLockscreenNotifications.setChecked(getLockscreenAllowPrivateNotifications());
-            }
-        }
-
         return root;
     }
 
-    private boolean getDeviceLockscreenNotificationsEnabled() {
-        return 0 != Settings.Global.getInt(getContentResolver(),
-                Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
-    }
-
-    private boolean getLockscreenAllowPrivateNotifications() {
-        return 0 != Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
-    }
-
-    private int getNumEnabledNotificationListeners() {
-        final String flat = Settings.Secure.getString(getContentResolver(),
-                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
-        if (flat == null || "".equals(flat)) return 0;
-        final String[] components = flat.split(":");
-        return components.length;
-    }
-
     private boolean isNonMarketAppsAllowed() {
         return Settings.Global.getInt(getContentResolver(),
                                       Settings.Global.INSTALL_NON_MARKET_APPS, 0) > 0;
@@ -617,10 +560,6 @@
         } else if (KEY_TOGGLE_VERIFY_APPLICATIONS.equals(key)) {
             Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_ENABLE,
                     mToggleVerifyApps.isChecked() ? 1 : 0);
-        } else if (KEY_LOCK_SCREEN_NOTIFICATIONS.equals(key)) {
-            Settings.Secure.putInt(getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
-                    mLockscreenNotifications.isChecked() ? 1 : 0);
         } else {
             // If we didn't handle it, let preferences handle it.
             return super.onPreferenceTreeClick(preferenceScreen, preference);
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 1c7bb59..0d5839b 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -86,6 +86,7 @@
     public static class PrintSettingsActivity extends SettingsActivity { /* empty */ }
     public static class PrintJobSettingsActivity extends SettingsActivity { /* empty */ }
     public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class NotificationSettingsActivity extends SettingsActivity { /* empty */ }
 
     public static class TopLevelSettings extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 8582bc6..e49d827 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -95,12 +95,13 @@
 import com.android.settings.deviceinfo.UsbSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.indexer.Index;
-import com.android.settings.indexer.IndexableData;
+import com.android.settings.indexer.IndexableRef;
 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
 import com.android.settings.inputmethod.SpellCheckersSettings;
 import com.android.settings.inputmethod.UserDictionaryList;
 import com.android.settings.location.LocationSettings;
+import com.android.settings.net.DataUsageMeteredSettings;
 import com.android.settings.nfc.AndroidBeam;
 import com.android.settings.nfc.PaymentSettings;
 import com.android.settings.print.PrintJobSettingsFragment;
@@ -341,68 +342,73 @@
         }
     };
 
+    private static int NO_DATA_RES_ID = 0;
+
     /**
-     * Searchable data description.
+     * Indexable data description.
      *
      * Known restriction: we are only searching (for now) the first level of Settings.
      */
-    private static IndexableData[] INDEXABLE_DATA = new IndexableData[] {
-            new IndexableData(1, R.xml.wifi_settings,
-                    "com.android.settings.wifi.WifiSettings",
+    private static IndexableRef[] INDEXABLE_REFS = new IndexableRef[] {
+            new IndexableRef(1, NO_DATA_RES_ID,
+                    WifiSettings.class.getName(),
                     R.drawable.ic_settings_wireless),
-            new IndexableData(2, R.xml.bluetooth_settings,
-                    "com.android.settings.bluetooth.BluetoothSettings",
+            new IndexableRef(2, R.xml.bluetooth_settings,
+                    BluetoothSettings.class.getName(),
                     R.drawable.ic_settings_bluetooth2),
-            new IndexableData(3, R.xml.data_usage_metered_prefs,
-                    "com.android.settings.net.DataUsageMeteredSettings",
+            new IndexableRef(3, R.xml.data_usage_metered_prefs,
+                    DataUsageMeteredSettings.class.getName(),
                     R.drawable.ic_settings_data_usage),
-            new IndexableData(4, R.xml.wireless_settings,
-                    "com.android.settings.WirelessSettings",
+            new IndexableRef(4, R.xml.wireless_settings,
+                    WirelessSettings.class.getName(),
                     R.drawable.empty_icon),
-            new IndexableData(5, R.xml.home_selection,
-                    "com.android.settings.HomeSettings",
+            new IndexableRef(5, R.xml.home_selection,
+                    HomeSettings.class.getName(),
                     R.drawable.ic_settings_home),
-            new IndexableData(6, R.xml.sound_settings,
-                    "com.android.settings.SoundSettings",
+            new IndexableRef(6, R.xml.sound_settings,
+                    SoundSettings.class.getName(),
                     R.drawable.ic_settings_sound),
-            new IndexableData(7, R.xml.display_settings,
-                    "com.android.settings.DisplaySettings",
+            new IndexableRef(7, R.xml.display_settings,
+                    DisplaySettings.class.getName(),
                     R.drawable.ic_settings_display),
-            new IndexableData(8, R.xml.device_info_memory,
-                    "com.android.settings.deviceinfo.Memory",
+            new IndexableRef(7, NO_DATA_RES_ID,
+                    WallpaperTypeSettings.class.getName(),
+                    R.drawable.ic_settings_display),
+            new IndexableRef(8, R.xml.device_info_memory,
+                    Memory.class.getName(),
                     R.drawable.ic_settings_storage),
-            new IndexableData(9, R.xml.power_usage_summary,
-                    "com.android.settings.fuelgauge.PowerUsageSummary",
+            new IndexableRef(9, R.xml.power_usage_summary,
+                    PowerUsageSummary.class.getName(),
                     R.drawable.ic_settings_battery),
-            new IndexableData(10, R.xml.user_settings,
-                    "com.android.settings.users.UserSettings",
+            new IndexableRef(10, R.xml.user_settings,
+                    UserSettings.class.getName(),
                     R.drawable.ic_settings_multiuser),
-            new IndexableData(11, R.xml.location_settings,
-                    "com.android.settings.location.LocationSettings",
+            new IndexableRef(11, R.xml.location_settings,
+                    LocationSettings.class.getName(),
                     R.drawable.ic_settings_location),
-            new IndexableData(12, R.xml.security_settings,
-                    "com.android.settings.SecuritySettings",
+            new IndexableRef(12, R.xml.security_settings,
+                    SecuritySettings.class.getName(),
                     R.drawable.ic_settings_security),
-            new IndexableData(13, R.xml.language_settings,
-                    "com.android.settings.inputmethod.InputMethodAndLanguageSettings",
+            new IndexableRef(13, R.xml.language_settings,
+                    InputMethodAndLanguageSettings.class.getName(),
                     R.drawable.ic_settings_language),
-            new IndexableData(14, R.xml.privacy_settings,
-                    "com.android.settings.PrivacySettings",
+            new IndexableRef(14, R.xml.privacy_settings,
+                    PrivacySettings.class.getName(),
                     R.drawable.ic_settings_backup),
-            new IndexableData(15, R.xml.date_time_prefs,
-                    "com.android.settings.DateTimeSettings",
+            new IndexableRef(15, R.xml.date_time_prefs,
+                    DateTimeSettings.class.getName(),
                     R.drawable.ic_settings_date_time),
-            new IndexableData(16, R.xml.accessibility_settings,
-                    "com.android.settings.accessibility.AccessibilitySettings",
+            new IndexableRef(16, R.xml.accessibility_settings,
+                    AccessibilitySettings.class.getName(),
                     R.drawable.ic_settings_accessibility),
-            new IndexableData(17, R.xml.print_settings,
-                    "com.android.settings.print.PrintSettingsFragment",
+            new IndexableRef(17, R.xml.print_settings,
+                    PrintSettingsFragment.class.getName(),
                     com.android.internal.R.drawable.ic_print),
-            new IndexableData(18, R.xml.development_prefs,
-                    "com.android.settings.DevelopmentSettings",
+            new IndexableRef(18, R.xml.development_prefs,
+                    DevelopmentSettings.class.getName(),
                     R.drawable.ic_settings_development),
-            new IndexableData(19, R.xml.device_info_settings,
-                    "com.android.settings.DeviceInfoSettings",
+            new IndexableRef(19, R.xml.device_info_settings,
+                    DeviceInfoSettings.class.getName(),
                     R.drawable.ic_settings_about),
     };
 
@@ -546,7 +552,7 @@
             getWindow().setUiOptions(getIntent().getIntExtra(EXTRA_UI_OPTIONS, 0));
         }
 
-        Index.getInstance(this).addIndexableData(INDEXABLE_DATA);
+        Index.getInstance(this).addIndexableData(INDEXABLE_REFS);
         Index.getInstance(this).update();
 
         mAuthenticatorHelper = new AuthenticatorHelper();
@@ -1574,9 +1580,6 @@
                                 view.findViewById(com.android.internal.R.id.summary);
                         break;
                 }
-                if (holder.mIcon != null) {
-                    holder.mIcon.setBackgroundResource(R.color.background_drawer_icon);
-                }
                 view.setTag(holder);
             } else {
                 view = convertView;
@@ -1644,7 +1647,18 @@
                     Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
                     setHeaderIcon(holder, icon);
                 } else {
-                    holder.mIcon.setImageResource(header.iconRes);
+                    if (header.iconRes > 0) {
+                        holder.mIcon.setImageResource(header.iconRes);
+                    } else {
+                        holder.mIcon.setImageDrawable(null);
+                    }
+                }
+                if (holder.mIcon != null) {
+                    if (header.iconRes > 0) {
+                        holder.mIcon.setBackgroundResource(R.color.background_drawer_icon);
+                    } else {
+                        holder.mIcon.setBackground(null);
+                    }
                 }
                 holder.mTitle.setText(header.getTitle(getContext().getResources()));
                 CharSequence summary = header.getSummary(getContext().getResources());
diff --git a/src/com/android/settings/SoundSettings.java b/src/com/android/settings/SoundSettings.java
index d506864..45fd0db 100644
--- a/src/com/android/settings/SoundSettings.java
+++ b/src/com/android/settings/SoundSettings.java
@@ -75,7 +75,6 @@
     private static final String KEY_DOCK_AUDIO_SETTINGS = "dock_audio";
     private static final String KEY_DOCK_SOUNDS = "dock_sounds";
     private static final String KEY_DOCK_AUDIO_MEDIA_ENABLED = "dock_audio_media_enabled";
-    private static final String KEY_ZEN_MODE = "zen_mode";
 
     private static final String[] NEED_VOICE_CAPABILITY = {
             KEY_RINGTONE, KEY_DTMF_TONE, KEY_CATEGORY_CALLS,
@@ -102,7 +101,6 @@
     private CheckBoxPreference mDockSounds;
     private Intent mDockIntent;
     private CheckBoxPreference mDockAudioMediaEnabled;
-    private ZenModeListPreference mZenModeListPreference;
 
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
@@ -229,9 +227,6 @@
         };
 
         initDockSettings();
-
-        mZenModeListPreference = (ZenModeListPreference) findPreference(KEY_ZEN_MODE);
-        mZenModeListPreference.init();
     }
 
     @Override
@@ -253,8 +248,13 @@
 
     private void updateRingtoneName(int type, Preference preference, int msg) {
         if (preference == null) return;
-        Context context = getActivity();
-        if (context == null) return;
+        final CharSequence summary = updateRingtoneName(getActivity(), type);
+        if (summary == null) return;
+        mHandler.sendMessage(mHandler.obtainMessage(msg, summary));
+    }
+
+    public static CharSequence updateRingtoneName(Context context, int type) {
+        if (context == null) return null;
         Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
         CharSequence summary = context.getString(com.android.internal.R.string.ringtone_unknown);
         // Is it a silent ringtone?
@@ -275,7 +275,7 @@
                 // Unknown title for the ringtone
             }
         }
-        mHandler.sendMessage(mHandler.obtainMessage(msg, summary));
+        return summary;
     }
 
     private void lookupRingtoneNames() {
diff --git a/src/com/android/settings/WallpaperTypeSettings.java b/src/com/android/settings/WallpaperTypeSettings.java
index fa5f0ac..f46315a 100644
--- a/src/com/android/settings/WallpaperTypeSettings.java
+++ b/src/com/android/settings/WallpaperTypeSettings.java
@@ -16,18 +16,23 @@
 
 package com.android.settings;
 
-import android.app.Activity;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
+import com.android.settings.indexer.Indexable;
+import com.android.settings.indexer.IndexableData;
+import com.android.settings.indexer.IndexableRef;
 
+import java.util.ArrayList;
 import java.util.List;
 
-public class WallpaperTypeSettings extends SettingsPreferenceFragment {
+public class WallpaperTypeSettings extends SettingsPreferenceFragment implements Indexable {
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -38,9 +43,9 @@
 
     private void populateWallpaperTypes() {
         // Search for activities that satisfy the ACTION_SET_WALLPAPER action
-        Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
+        final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
         final PackageManager pm = getPackageManager();
-        List<ResolveInfo> rList = pm.queryIntentActivities(intent,
+        final List<ResolveInfo> rList = pm.queryIntentActivities(intent,
                 PackageManager.MATCH_DEFAULT_ONLY);
 
         final PreferenceScreen parent = getPreferenceScreen();
@@ -58,4 +63,42 @@
             parent.addPreference(pref);
         }
     }
+
+    public static final IndexDataProvider INDEX_DATA_PROVIDER =
+        new IndexDataProvider() {
+            @Override
+            public List<IndexableRef> getRefsToIndex(Context context) {
+                return null;
+            }
+
+            @Override
+            public List<IndexableData> getRawDataToIndex(Context context) {
+                final List<IndexableData> result = new ArrayList<IndexableData>();
+
+                final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
+                final PackageManager pm = context.getPackageManager();
+                final List<ResolveInfo> rList = pm.queryIntentActivities(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY);
+
+                // Add indexable data for each of the matching activities
+                for (ResolveInfo info : rList) {
+                    Intent prefIntent = new Intent(intent);
+                    prefIntent.setComponent(new ComponentName(
+                            info.activityInfo.packageName, info.activityInfo.name));
+                    CharSequence label = info.loadLabel(pm);
+                    if (label == null) label = info.activityInfo.packageName;
+
+                    IndexableData data = new IndexableData();
+                    data.title = label.toString();
+                    data.fragmentTitle = context.getResources().getString(
+                            R.string.wallpaper_settings_fragment_title);
+                    data.intentAction = intent.getAction();
+                    data.intentTargetPackage = info.activityInfo.packageName;
+                    data.intentTargetClass = info.activityInfo.name;
+                    result.add(data);
+                }
+
+                return result;
+            }
+        };
 }
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index d6bb82d..9c1e300 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -18,14 +18,8 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManagerNative;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
@@ -33,7 +27,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -42,7 +35,6 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
-import android.util.Log;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
@@ -68,20 +60,11 @@
  */
 public class AccessibilitySettings extends SettingsPreferenceFragment implements DialogCreatable,
         Preference.OnPreferenceChangeListener {
-    private static final String LOG_TAG = "AccessibilitySettings";
-
-    private static final String DEFAULT_SCREENREADER_MARKET_LINK =
-            "market://search?q=pname:com.google.android.marvin.talkback";
 
     private static final float LARGE_FONT_SCALE = 1.3f;
 
-    private static final String SYSTEM_PROPERTY_MARKET_URL = "ro.screenreader.market";
-
     static final char ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR = ':';
 
-    private static final String KEY_INSTALL_ACCESSIBILITY_SERVICE_OFFERED_ONCE =
-            "key_install_accessibility_service_offered_once";
-
     // Preference categories
     private static final String SERVICES_CATEGORY = "services_category";
     private static final String SYSTEM_CATEGORY = "system_category";
@@ -125,9 +108,6 @@
     // presentation.
     private static final long DELAY_UPDATE_SERVICES_MILLIS = 1000;
 
-    // Dialog IDs.
-    private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
-
     // Auxiliary members.
     final static SimpleStringSplitter sStringColonSplitter =
             new SimpleStringSplitter(ENABLED_ACCESSIBILITY_SERVICES_SEPARATOR);
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index e10b74f..a028adf 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -46,7 +46,7 @@
     public void setPercent(double percentOfMax, double percentOfTotal) {
         mProgress = (int) Math.ceil(percentOfMax);
         mProgressText = getContext().getResources().getString(
-                R.string.percentage, (int) Math.ceil(percentOfTotal));
+                R.string.percentage, (int) (percentOfTotal+.5));
         notifyChanged();
     }
 
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 24b5060..8a729941 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -238,14 +238,21 @@
             addNotAvailableMessage();
             return;
         }
+        int dischargeAmount = mStatsType == BatteryStats.STATS_SINCE_CHARGED
+                ? mStatsHelper.getStats().getHighDischargeAmountSinceCharge()
+                : (mStatsHelper.getStats().getDischargeStartLevel()
+                        - mStatsHelper.getStats().getDischargeCurrentLevel());
+        if (dischargeAmount < 0) {
+            dischargeAmount = 0;
+        }
         mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
         List<BatterySipper> usageList = mStatsHelper.getUsageList();
         for (int i=0; i<usageList.size(); i++) {
             BatterySipper sipper = usageList.get(i);
             if ((sipper.value*60*60) < MIN_POWER_THRESHOLD) continue;
             final double percentOfTotal =
-                    ((sipper.value / mStatsHelper.getTotalPower()) * 100);
-            if (percentOfTotal < 1) continue;
+                    ((sipper.value / mStatsHelper.getTotalPower()) * dischargeAmount);
+            if (((int)(percentOfTotal+.5)) < 1) continue;
             BatteryEntry entry = new BatteryEntry(getActivity(), mHandler, mUm, sipper);
             PowerGaugePreference pref =
                     new PowerGaugePreference(getActivity(), entry.getIcon(), entry);
diff --git a/src/com/android/settings/indexer/Index.java b/src/com/android/settings/indexer/Index.java
index 5139e0c..19b545f 100644
--- a/src/com/android/settings/indexer/Index.java
+++ b/src/com/android/settings/indexer/Index.java
@@ -34,6 +34,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -45,7 +46,7 @@
 
 public class Index {
 
-    private static final String LOG_TAG = "Indexer";
+    private static final String LOG_TAG = "Index";
 
     // Those indices should match the indices of SELECT_COLUMNS !
     public static final int COLUMN_INDEX_TITLE = 1;
@@ -81,7 +82,8 @@
     private static Index sInstance;
 
     private final AtomicBoolean mIsAvailable = new AtomicBoolean(false);
-    private final List<IndexableData> mDataToIndex = new ArrayList<IndexableData>();
+
+    private final UpdateData mUpdateData = new UpdateData();
 
     private final Context mContext;
 
@@ -103,6 +105,42 @@
         return mIsAvailable.get();
     }
 
+    public void addIndexableData(IndexableRef[] array) {
+        synchronized (mUpdateData) {
+            final int count = array.length;
+            for (int n = 0; n < count; n++) {
+                mUpdateData.dataToAdd.add(array[n]);
+            }
+        }
+    }
+
+    public void deleteIndexableData(String[] array) {
+        synchronized (mUpdateData) {
+            final int count = array.length;
+            for (int n = 0; n < count; n++) {
+                mUpdateData.dataToDelete.add(array[n]);
+            }
+        }
+    }
+
+    public boolean update() {
+        synchronized (mUpdateData) {
+            final UpdateIndexTask task = new UpdateIndexTask();
+            task.execute(mUpdateData);
+            try {
+                final boolean result = task.get();
+                mUpdateData.clear();
+                return result;
+            } catch (InterruptedException e) {
+                Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
+                return false;
+            } catch (ExecutionException e) {
+                Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
+                return false;
+            }
+        }
+    }
+
     public Cursor search(String query) {
         final String sql = buildSQL(query);
         Log.d(LOG_TAG, "Query: " + sql);
@@ -160,31 +198,6 @@
         return sb.toString();
     }
 
-    public void addIndexableData(IndexableData data) {
-        mDataToIndex.add(data);
-    }
-
-    public void addIndexableData(IndexableData[] array) {
-        final int count = array.length;
-        for (int n = 0; n < count; n++) {
-            addIndexableData(array[n]);
-        }
-    }
-
-    public boolean update() {
-        final IndexTask task = new IndexTask();
-        task.execute();
-        try {
-            return task.get();
-        } catch (InterruptedException e) {
-            Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
-            return false;
-        } catch (ExecutionException e) {
-            Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
-            return false;
-        }
-    }
-
     private SQLiteDatabase getReadableDatabase() {
         return IndexDatabaseHelper.getInstance(mContext).getReadableDatabase();
     }
@@ -194,9 +207,27 @@
     }
 
     /**
+     * A private class to describe the update data for the Index database
+     */
+    private class UpdateData {
+        public List<IndexableRef> dataToAdd;
+        public List<String> dataToDelete;
+
+        public UpdateData() {
+            dataToAdd = new ArrayList<IndexableRef>();
+            dataToDelete = new ArrayList<String>();
+        }
+
+        public void clear() {
+            dataToAdd.clear();
+            dataToDelete.clear();
+        }
+    }
+
+    /**
      * A private class for updating the Index database
      */
-    private class IndexTask extends AsyncTask<Void, Integer, Boolean> {
+    private class UpdateIndexTask extends AsyncTask<UpdateData, Integer, Boolean> {
 
         @Override
         protected void onPreExecute() {
@@ -211,41 +242,123 @@
         }
 
         @Override
-        protected Boolean doInBackground(Void... params) {
-            final SQLiteDatabase database = getWritableDatabase();
+        protected Boolean doInBackground(UpdateData... params) {
             boolean result = false;
-            final Locale locale = Locale.getDefault();
-            final String localeStr = locale.toString();
-            if (isLocaleAlreadyIndexed(database, locale)) {
-                Log.d(LOG_TAG, "Locale '" + localeStr + "' is already indexed");
-                return true;
-            }
-            final long current = System.currentTimeMillis();
+
+            final List<IndexableRef> dataToAdd = params[0].dataToAdd;
+            final List<String> dataToDelete = params[0].dataToDelete;
+            final SQLiteDatabase database = getWritableDatabase();
+            final String localeStr = Locale.getDefault().toString();
+
             try {
                 database.beginTransaction();
-                final int count = mDataToIndex.size();
-                for (int n = 0; n < count; n++) {
-                    final IndexableData data = mDataToIndex.get(n);
-                    indexFromResource(database, locale, data.xmlResId, data.fragmentName,
-                            data.iconResId, data.rank);
+                if (dataToAdd.size() > 0) {
+                    processDataToAdd(database, localeStr, dataToAdd);
+                }
+                if (dataToDelete.size() > 0) {
+                    processDataToDelete(database, localeStr, dataToDelete);
                 }
                 database.setTransactionSuccessful();
                 result = true;
             } finally {
                 database.endTransaction();
             }
+            return result;
+        }
+
+        private boolean processDataToDelete(SQLiteDatabase database, String localeStr,
+                                         List<String> dataToDelete) {
+
+            boolean result = false;
+            final long current = System.currentTimeMillis();
+
+            final int count = dataToDelete.size();
+            for (int n = 0; n < count; n++) {
+                final String data = dataToDelete.get(n);
+                delete(database, data);
+            }
+
+            final long now = System.currentTimeMillis();
+            Log.d(LOG_TAG, "Deleting data for locale '" + localeStr + "' took " +
+                    (now - current) + " millis");
+            return result;
+        }
+
+        private boolean processDataToAdd(SQLiteDatabase database, String localeStr,
+                                         List<IndexableRef> dataToAdd) {
+            if (isLocaleAlreadyIndexed(database, localeStr)) {
+                Log.d(LOG_TAG, "Locale '" + localeStr + "' is already indexed");
+                return true;
+            }
+
+            boolean result = false;
+            final long current = System.currentTimeMillis();
+
+            final int count = dataToAdd.size();
+            for (int n = 0; n < count; n++) {
+                final IndexableRef ref = dataToAdd.get(n);
+                indexOneRef(database, localeStr, ref);
+            }
+
             final long now = System.currentTimeMillis();
             Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " +
                     (now - current) + " millis");
             return result;
         }
 
-        private boolean isLocaleAlreadyIndexed(SQLiteDatabase database, Locale locale) {
+        private void indexOneRef(SQLiteDatabase database, String localeStr, IndexableRef ref) {
+            if (ref.xmlResId > 0) {
+                indexFromResource(database, localeStr, ref.xmlResId, ref.fragmentName,
+                        ref.iconResId, ref.rank);
+            } else if (!TextUtils.isEmpty(ref.fragmentName)) {
+                indexRawData(database, localeStr, ref);
+            }
+        }
+
+        private void indexRawData(SQLiteDatabase database, String localeStr, IndexableRef ref) {
+            try {
+                final Class<?> clazz = Class.forName(ref.fragmentName);
+                if (Indexable.class.isAssignableFrom(clazz)) {
+                    final Field f = clazz.getField("INDEX_DATA_PROVIDER");
+                    final Indexable.IndexDataProvider provider =
+                            (Indexable.IndexDataProvider) f.get(null);
+
+                    final List<IndexableData> data = provider.getRawDataToIndex(mContext);
+
+                    final int size = data.size();
+                    for (int i = 0; i < size; i++) {
+                        IndexableData raw = data.get(i);
+
+                        // Should be the same locale as the one we are processing
+                        if (!raw.locale.toString().equalsIgnoreCase(localeStr)) {
+                            continue;
+                        }
+
+                        inserOneRowWithFilteredData(database, localeStr,
+                                raw.title,
+                                raw.summary,
+                                ref.fragmentName,
+                                raw.fragmentTitle,
+                                ref.iconResId,
+                                ref.rank,
+                                raw.keywords);
+                    }
+                }
+            } catch (ClassNotFoundException e) {
+                Log.e(LOG_TAG, "Cannot find class: " + ref.fragmentName, e);
+            } catch (NoSuchFieldException e) {
+                Log.e(LOG_TAG, "Cannot find field 'INDEX_DATA_PROVIDER'", e);
+            } catch (IllegalAccessException e) {
+                Log.e(LOG_TAG, "Illegal access to field 'INDEX_DATA_PROVIDER'", e);
+            }
+        }
+
+        private boolean isLocaleAlreadyIndexed(SQLiteDatabase database, String locale) {
             Cursor cursor = null;
             boolean result = false;
             final StringBuilder sb = new StringBuilder(IndexColumns.LOCALE);
             sb.append(" = ");
-            DatabaseUtils.appendEscapedSQLString(sb, locale.toString());
+            DatabaseUtils.appendEscapedSQLString(sb, locale);
             try {
                 // We care only for 1 row
                 cursor = database.query(Tables.TABLE_PREFS_INDEX, null,
@@ -260,10 +373,9 @@
             return result;
         }
 
-        private void indexFromResource(SQLiteDatabase database, Locale locale, int xmlResId,
+        private void indexFromResource(SQLiteDatabase database, String localeStr, int xmlResId,
                 String fragmentName, int iconResId, int rank) {
             XmlResourceParser parser = null;
-            final String localeStr = locale.toString();
             try {
                 parser = mContext.getResources().getXml(xmlResId);
 
@@ -369,6 +481,13 @@
             database.insertOrThrow(Tables.TABLE_PREFS_INDEX, null, values);
         }
 
+        private int delete(SQLiteDatabase database, String title) {
+            final String whereClause = IndexColumns.DATA_TITLE + "=?";
+            final String[] whereArgs = new String[] { title };
+
+            return database.delete(Tables.TABLE_PREFS_INDEX, whereClause, whereArgs);
+        }
+
         private String getDataTitle(AttributeSet attrs) {
             return getData(attrs,
                     com.android.internal.R.styleable.Preference,
diff --git a/src/com/android/settings/indexer/Indexable.java b/src/com/android/settings/indexer/Indexable.java
new file mode 100644
index 0000000..1b29b75
--- /dev/null
+++ b/src/com/android/settings/indexer/Indexable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 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.settings.indexer;
+
+import android.content.Context;
+
+import java.util.List;
+
+/**
+ * Interface for classes whose instances can provide data for indexing.
+ *
+ * Classes implementing the Indexable interface must have a static field called
+ * <code>INDEX_DATA_PROVIDER</code>, which is an object implementing the
+ * {@link Indexable.IndexDataProvider Indexable.IndexDataProvider} interface.
+ *
+ * See {@link IndexableRef} and {@link IndexableData}.
+ *
+ */
+public interface Indexable {
+
+    public interface IndexDataProvider {
+        /**
+         * Return a list of references for indexing. See {@link IndexableRef}
+         *
+         * @param context the context
+         * @return a list of {@link IndexableRef} references. Can be null.
+         */
+        List<IndexableRef> getRefsToIndex(Context context);
+
+        /**
+         * Return a list of raw data for indexing. See {@link IndexableData}
+         *
+         * @param context the context
+         * @return a list of {@link IndexableData} references. Can be null.
+         */
+        List<IndexableData> getRawDataToIndex(Context context);
+    }
+}
diff --git a/src/com/android/settings/indexer/IndexableData.java b/src/com/android/settings/indexer/IndexableData.java
index 61714a2..ca388de 100644
--- a/src/com/android/settings/indexer/IndexableData.java
+++ b/src/com/android/settings/indexer/IndexableData.java
@@ -16,17 +16,30 @@
 
 package com.android.settings.indexer;
 
+import java.util.Locale;
+
+/**
+ * Indexable Data.
+ *
+ * This is the raw data used by the Indexer and should match its data model.
+ *
+ * See {@link Indexable} and {@link IndexableRef}.
+ */
 public class IndexableData {
 
-    public int rank;
-    public int xmlResId;
-    public String fragmentName;
-    public int iconResId;
+    public Locale locale;
 
-    public IndexableData(int rank, int dataResId, String name, int iconResId) {
-        this.rank = rank;
-        this.xmlResId = dataResId;
-        this.fragmentName = name;
-        this.iconResId = iconResId;
+    public String title;
+    public String summary;
+    public String keywords;
+
+    public String intentAction;
+    public String intentTargetPackage;
+    public String intentTargetClass;
+
+    public String fragmentTitle;
+
+    public IndexableData() {
+        locale = Locale.getDefault();
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/indexer/IndexableRef.java b/src/com/android/settings/indexer/IndexableRef.java
new file mode 100644
index 0000000..c1ebcca
--- /dev/null
+++ b/src/com/android/settings/indexer/IndexableRef.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 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.settings.indexer;
+
+/**
+ * Indexable Reference.
+ *
+ * This class wraps a set of information representing data that can be indexed for a high
+ * level (see {@link android.preference.PreferenceScreen}).
+ *
+ * rank: is the rank of the data (basically its order in the list of Settings)
+ * xmlResId: is the resource Id of a PreferenceScreen xml file
+ * fragmentName: is the fragment class name associated with the data
+ * iconRedId: is the resource Id of an icon that represents the data
+ *
+ * See {@link Indexable} and {@link IndexableData}.
+ *
+ */
+public class IndexableRef {
+
+    public int rank;
+    public int xmlResId;
+    public String fragmentName;
+    public int iconResId;
+
+    public IndexableRef(int rank, int dataResId, String name, int iconResId) {
+        this.rank = rank;
+        this.xmlResId = dataResId;
+        this.fragmentName = name;
+        this.iconResId = iconResId;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 40156cf..b159e99 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -77,7 +77,6 @@
         final int padding = activity.getResources().getDimensionPixelSize(
                 R.dimen.action_bar_switch_padding);
         mSwitch.setPaddingRelative(0, 0, padding, 0);
-        mSwitch.setOnCheckedChangeListener(this);
     }
 
     @Override
@@ -112,6 +111,7 @@
         super.onResume();
         mValidListener = true;
         createPreferenceHierarchy();
+        mSwitch.setOnCheckedChangeListener(this);
     }
 
     @Override
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index a3003e8..1d4fe71 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -45,6 +45,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.MissingResourceException;
 import java.util.Set;
 
 public class TextToSpeechSettings extends SettingsPreferenceFragment implements
@@ -277,25 +278,32 @@
         if (mCurrentDefaultLocale == null || mAvailableStrLocals == null) {
             return false;
         }
-        int defaultAvailable = mTts.setLanguage(mCurrentDefaultLocale);
 
-        // Check if language is listed in CheckVoices Action result as available voice.
-        String defaultLocaleStr = mCurrentDefaultLocale.getISO3Language();
         boolean notInAvailableLangauges = true;
-        if (!TextUtils.isEmpty(mCurrentDefaultLocale.getISO3Country())) {
-            defaultLocaleStr += "-" + mCurrentDefaultLocale.getISO3Country();
-        }
-        if (!TextUtils.isEmpty(mCurrentDefaultLocale.getVariant())) {
-            defaultLocaleStr += "-" + mCurrentDefaultLocale.getVariant();
-        }
-
-        for (String loc : mAvailableStrLocals) {
-            if (loc.equalsIgnoreCase(defaultLocaleStr)) {
-              notInAvailableLangauges = false;
-              break;
+        try {
+            // Check if language is listed in CheckVoices Action result as available voice.
+            String defaultLocaleStr = mCurrentDefaultLocale.getISO3Language();
+            if (!TextUtils.isEmpty(mCurrentDefaultLocale.getISO3Country())) {
+                defaultLocaleStr += "-" + mCurrentDefaultLocale.getISO3Country();
             }
+            if (!TextUtils.isEmpty(mCurrentDefaultLocale.getVariant())) {
+                defaultLocaleStr += "-" + mCurrentDefaultLocale.getVariant();
+            }
+
+            for (String loc : mAvailableStrLocals) {
+                if (loc.equalsIgnoreCase(defaultLocaleStr)) {
+                  notInAvailableLangauges = false;
+                  break;
+                }
+            }
+        } catch (MissingResourceException e) {
+            if (DBG) Log.wtf(TAG, "MissingResourceException", e);
+            updateEngineStatus(R.string.tts_status_not_supported);
+            updateWidgetState(false);
+            return false;
         }
 
+        int defaultAvailable = mTts.setLanguage(mCurrentDefaultLocale);
         if (defaultAvailable == TextToSpeech.LANG_NOT_SUPPORTED ||
                 defaultAvailable == TextToSpeech.LANG_MISSING_DATA ||
                 notInAvailableLangauges) {
@@ -314,7 +322,6 @@
         }
     }
 
-
     /**
      * Ask the current default engine to return a string of sample text to be
      * spoken to the user.
@@ -357,16 +364,21 @@
 
     private String getDefaultSampleString() {
         if (mTts != null && mTts.getLanguage() != null) {
-            final String currentLang = mTts.getLanguage().getISO3Language();
-            String[] strings = getActivity().getResources().getStringArray(
-                    R.array.tts_demo_strings);
-            String[] langs = getActivity().getResources().getStringArray(
-                    R.array.tts_demo_string_langs);
+            try {
+                final String currentLang = mTts.getLanguage().getISO3Language();
+                String[] strings = getActivity().getResources().getStringArray(
+                        R.array.tts_demo_strings);
+                String[] langs = getActivity().getResources().getStringArray(
+                        R.array.tts_demo_string_langs);
 
-            for (int i = 0; i < strings.length; ++i) {
-                if (langs[i].equals(currentLang)) {
-                    return strings[i];
+                for (int i = 0; i < strings.length; ++i) {
+                    if (langs[i].equals(currentLang)) {
+                        return strings[i];
+                    }
                 }
+            } catch (MissingResourceException e) {
+                if (DBG) Log.wtf(TAG, "MissingResourceException", e);
+                // Ignore and fall back to default sample string
             }
         }
         return getString(R.string.tts_default_sample_string);
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index a6ef05c..d6e68a3 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -23,6 +23,9 @@
 import com.android.settings.R;
 import com.android.settings.RestrictedSettingsFragment;
 import com.android.settings.SettingsActivity;
+import com.android.settings.indexer.Indexable;
+import com.android.settings.indexer.IndexableData;
+import com.android.settings.indexer.IndexableRef;
 import com.android.settings.wifi.p2p.WifiP2pSettings;
 
 import android.app.ActionBar;
@@ -90,7 +93,7 @@
  * and menus.
  */
 public class WifiSettings extends RestrictedSettingsFragment
-        implements DialogInterface.OnClickListener  {
+        implements DialogInterface.OnClickListener, Indexable  {
     private static final String TAG = "WifiSettings";
     private static final int MENU_ID_WPS_PBC = Menu.FIRST;
     private static final int MENU_ID_WPS_PIN = Menu.FIRST + 1;
@@ -748,7 +751,8 @@
         switch (wifiState) {
             case WifiManager.WIFI_STATE_ENABLED:
                 // AccessPoints are automatically sorted with TreeSet.
-                final Collection<AccessPoint> accessPoints = constructAccessPoints();
+                final Collection<AccessPoint> accessPoints =
+                        constructAccessPoints(getActivity(), mWifiManager, mLastInfo, mLastState);
                 getPreferenceScreen().removeAll();
                 if(accessPoints.size() == 0) {
                     addMessagePreference(R.string.wifi_empty_list_wifi_on);
@@ -798,23 +802,26 @@
     }
 
     /** Returns sorted list of access points */
-    private List<AccessPoint> constructAccessPoints() {
+    private static List<AccessPoint> constructAccessPoints(Context context,
+            WifiManager wifiManager, WifiInfo lastInfo, DetailedState lastState) {
         ArrayList<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
         /** Lookup table to more quickly update AccessPoints by only considering objects with the
          * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
 
-        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        final List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
         if (configs != null) {
             for (WifiConfiguration config : configs) {
-                AccessPoint accessPoint = new AccessPoint(getActivity(), config);
-                accessPoint.update(mLastInfo, mLastState);
+                AccessPoint accessPoint = new AccessPoint(context, config);
+                if (lastInfo != null && lastState != null) {
+                    accessPoint.update(lastInfo, lastState);
+                }
                 accessPoints.add(accessPoint);
                 apMap.put(accessPoint.ssid, accessPoint);
             }
         }
 
-        final List<ScanResult> results = mWifiManager.getScanResults();
+        final List<ScanResult> results = wifiManager.getScanResults();
         if (results != null) {
             for (ScanResult result : results) {
                 // Ignore hidden and ad-hoc networks.
@@ -829,7 +836,7 @@
                         found = true;
                 }
                 if (!found) {
-                    AccessPoint accessPoint = new AccessPoint(getActivity(), result);
+                    AccessPoint accessPoint = new AccessPoint(context, result);
                     accessPoints.add(accessPoint);
                     apMap.put(accessPoint.ssid, accessPoint);
                 }
@@ -842,7 +849,7 @@
     }
 
     /** A restricted multimap for use in constructAccessPoints */
-    private class Multimap<K,V> {
+    private static class Multimap<K,V> {
         private final HashMap<K,List<V>> store = new HashMap<K,List<V>>();
         /** retrieve a non-null list of values with key K */
         List<V> getAll(K key) {
@@ -1141,10 +1148,10 @@
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
             int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
-            final Resources resources = getContext().getResources();
-            float titleHeight = resources.getFraction(R.dimen.setup_title_height, 1, 1);
-            float sideMargin = resources.getFraction(R.dimen.setup_border_width, 1, 1);
-            int bottom = resources.getDimensionPixelSize(R.dimen.setup_margin_bottom);
+            final Resources res = getContext().getResources();
+            float titleHeight = res.getFraction(R.dimen.setup_title_height, 1, 1);
+            float sideMargin = res.getFraction(R.dimen.setup_border_width, 1, 1);
+            int bottom = res.getDimensionPixelSize(R.dimen.setup_margin_bottom);
             setPaddingRelative(
                     (int) (parentWidth * sideMargin),
                     0,
@@ -1158,4 +1165,39 @@
         }
     }
 
+    public static final Indexable.IndexDataProvider INDEX_DATA_PROVIDER =
+        new Indexable.IndexDataProvider() {
+            @Override
+            public List<IndexableRef> getRefsToIndex(Context context) {
+                return null;
+            }
+
+            @Override
+            public List<IndexableData> getRawDataToIndex(Context context) {
+                final List<IndexableData> result = new ArrayList<IndexableData>();
+                final Resources res = context.getResources();
+
+                // Add fragment title
+                IndexableData data = new IndexableData();
+                data.title = res.getString(R.string.wifi_settings);
+                data.fragmentTitle = res.getString(R.string.wifi_settings);
+                result.add(data);
+
+                // Add available Wi-Fi access points
+                WifiManager wifiManager =
+                        (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+                final Collection<AccessPoint> accessPoints =
+                        constructAccessPoints(context, wifiManager, null, null);
+                for (AccessPoint accessPoint : accessPoints) {
+                    // We are indexing only the saved Wi-Fi networks.
+                    if (accessPoint.getConfig() == null) continue;
+                    data = new IndexableData();
+                    data.title = accessPoint.getTitle().toString();
+                    data.fragmentTitle = res.getString(R.string.wifi_settings);
+                    result.add(data);
+                }
+
+                return result;
+            }
+        };
 }