Finally, a place for notification settings.

Consolidated under the new Notifications settings are:

  - Ringtone (from Sound)
  - Zen Mode (from Sound)
  - Pulse LED (from Display)
  - Heads-Up Notifications (from Display)
  - Notification Access (from Security)
  - Show when locked (from Security)

Change-Id: I214d03ba1e356e088323a3058d98d390b8a8f988
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/strings.xml b/res/values/strings.xml
index f95f881..5b50de0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5006,25 +5006,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/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/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() {