Update Notification preferences UI in new IA.

- Refactored ConfigureNotificationSettings to be more modular
- And tests

Bug: 31799948
Test: RunSettingsRoboTests
Change-Id: I2ecd8930a6aa501c1e625cab6ed25a46f3437e85
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 208737c..14b7899 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6159,7 +6159,7 @@
 
 
     <!-- Configure Notifications Settings title. [CHAR LIMIT=30] -->
-    <string name="configure_notification_settings">Configure notifications</string>
+    <string name="configure_notification_settings">Notification preferences</string>
 
     <!-- Configure Notifications: Advanced section header [CHAR LIMIT=30] -->
     <string name="advanced_section_header">Advanced</string>
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index 8778abb..2bdb790 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -30,4 +30,15 @@
             android:title="@string/lock_screen_notifications_title"
             android:summary="%s" />
 
+    <PreferenceCategory
+        android:key="lock_screen_notifications_profile_header"
+        android:title="@string/profile_section_header" >
+
+        <com.android.settings.notification.RestrictedDropDownPreference
+            android:key="lock_screen_notifications_profile"
+            android:title="@string/lock_screen_notifications_title"
+            android:summary="%s" />
+
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/res/xml/configure_notification_settings_profile.xml b/res/xml/configure_notification_settings_profile.xml
deleted file mode 100644
index 301f3c0..0000000
--- a/res/xml/configure_notification_settings_profile.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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"
-                  xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-        android:title="@string/configure_notification_settings" >
-
-    <PreferenceCategory
-            android:title="@string/profile_section_header" >
-
-        <com.android.settings.notification.RestrictedDropDownPreference
-            android:key="lock_screen_notifications_profile"
-            android:title="@string/lock_screen_notifications_title"
-            android:summary="%s" />
-
-    </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 3f53ec9..0ed49d5 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,54 +16,20 @@
 
 package com.android.settings.notification;
 
-import android.app.admin.DevicePolicyManager;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.TwoStatePreference;
-import android.util.Log;
+
 import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.R;
-import com.android.settings.RestrictedListPreference.RestrictedItem;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
 
 import java.util.ArrayList;
+import java.util.List;
 
-import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
-import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-public class ConfigureNotificationSettings extends SettingsPreferenceFragment {
+public class ConfigureNotificationSettings extends DashboardFragment {
     private static final String TAG = "ConfigNotiSettings";
 
-    private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
-    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications";
-    private static final String KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS =
-            "lock_screen_notifications_profile";
-
-    private final SettingsObserver mSettingsObserver = new SettingsObserver();
-
-    private Context mContext;
-
-    private TwoStatePreference mNotificationPulse;
-    private RestrictedDropDownPreference mLockscreen;
-    private RestrictedDropDownPreference mLockscreenProfile;
-    private boolean mSecure;
-    private boolean mSecureProfile;
-    private int mLockscreenSelectedValue;
-    private int mLockscreenSelectedValueProfile;
-    private int mProfileChallengeUserId;
+    private LockScreenNotificationPreferenceController mLockScreenNotificationController;
 
     @Override
     public int getMetricsCategory() {
@@ -71,310 +37,30 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mContext = getActivity();
-        mProfileChallengeUserId = Utils.getManagedProfileId(
-                UserManager.get(mContext), UserHandle.myUserId());
-
-        final LockPatternUtils utils = new LockPatternUtils(getActivity());
-        final boolean isUnified =
-                !utils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
-
-        mSecure = utils.isSecure(UserHandle.myUserId());
-        mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
-                && (utils.isSecure(mProfileChallengeUserId) || (isUnified && mSecure));
-
-        addPreferencesFromResource(R.xml.configure_notification_settings);
-
-        initPulse();
-        initLockscreenNotifications();
-
-        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
-            addPreferencesFromResource(R.xml.configure_notification_settings_profile);
-            initLockscreenNotificationsForProfile();
-        }
-
+    protected String getCategoryKey() {
+        return "";
     }
 
     @Override
-    public void onResume() {
-        super.onResume();
-        mSettingsObserver.register(true);
+    protected String getLogTag() {
+        return TAG;
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
-        mSettingsObserver.register(false);
+    protected int getPreferenceScreenResId() {
+        return R.xml.configure_notification_settings;
     }
 
-    // === Pulse notification light ===
-
-    private void initPulse() {
-        mNotificationPulse =
-                (TwoStatePreference) getPreferenceScreen().findPreference(KEY_NOTIFICATION_PULSE);
-        if (mNotificationPulse == null) {
-            Log.i(TAG, "Preference not found: " + KEY_NOTIFICATION_PULSE);
-            return;
-        }
-        if (!getResources()
-                .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
-            getPreferenceScreen().removePreference(mNotificationPulse);
-        } else {
-            updatePulse();
-            mNotificationPulse.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
-                @Override
-                public boolean onPreferenceChange(Preference preference, Object newValue) {
-                    final boolean val = (Boolean)newValue;
-                    return Settings.System.putInt(getContentResolver(),
-                            Settings.System.NOTIFICATION_LIGHT_PULSE,
-                            val ? 1 : 0);
-                }
-            });
-        }
-    }
-
-    private void updatePulse() {
-        if (mNotificationPulse == null) {
-            return;
-        }
-        try {
-            mNotificationPulse.setChecked(Settings.System.getInt(getContentResolver(),
-                    Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
-        } catch (Settings.SettingNotFoundException snfe) {
-            Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
-        }
-    }
-
-    private void initLockscreenNotifications() {
-        mLockscreen = (RestrictedDropDownPreference) getPreferenceScreen().findPreference(
-                KEY_LOCK_SCREEN_NOTIFICATIONS);
-        if (mLockscreen == null) {
-            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS);
-            return;
-        }
-
-        ArrayList<CharSequence> entries = new ArrayList<>();
-        ArrayList<CharSequence> values = new ArrayList<>();
-        entries.add(getString(R.string.lock_screen_notifications_summary_disable));
-        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable));
-
-        String summaryShowEntry = getString(R.string.lock_screen_notifications_summary_show);
-        String summaryShowEntryValue = Integer.toString(
-                R.string.lock_screen_notifications_summary_show);
-        entries.add(summaryShowEntry);
-        values.add(summaryShowEntryValue);
-        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
-                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
-
-        if (mSecure) {
-            String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
-            String summaryHideEntryValue = Integer.toString(
-                    R.string.lock_screen_notifications_summary_hide);
-            entries.add(summaryHideEntry);
-            values.add(summaryHideEntryValue);
-            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
-                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
-        }
-
-        mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()]));
-        mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()]));
-        updateLockscreenNotifications();
-        if (mLockscreen.getEntries().length > 1) {
-            mLockscreen.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
-                @Override
-                public boolean onPreferenceChange(Preference preference, Object newValue) {
-                    final int val = Integer.parseInt((String) newValue);
-                    if (val == mLockscreenSelectedValue) {
-                        return false;
-                    }
-                    final boolean enabled =
-                            val != R.string.lock_screen_notifications_summary_disable;
-                    final boolean show = val == R.string.lock_screen_notifications_summary_show;
-                    Settings.Secure.putInt(getContentResolver(),
-                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
-                    Settings.Secure.putInt(getContentResolver(),
-                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
-                    mLockscreenSelectedValue = val;
-                    return true;
-                }
-            });
-        } else {
-            // There is one or less option for the user, disable the drop down.
-            mLockscreen.setEnabled(false);
-        }
-    }
-
-    // === Lockscreen (public / private) notifications ===
-    private void initLockscreenNotificationsForProfile() {
-        mLockscreenProfile = (RestrictedDropDownPreference) getPreferenceScreen()
-                .findPreference(KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
-        if (mLockscreenProfile == null) {
-            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
-            return;
-        }
-        ArrayList<CharSequence> entries = new ArrayList<>();
-        ArrayList<CharSequence> values = new ArrayList<>();
-        entries.add(getString(R.string.lock_screen_notifications_summary_disable_profile));
-        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile));
-
-        String summaryShowEntry = getString(
-                R.string.lock_screen_notifications_summary_show_profile);
-        String summaryShowEntryValue = Integer.toString(
-                R.string.lock_screen_notifications_summary_show_profile);
-        entries.add(summaryShowEntry);
-        values.add(summaryShowEntryValue);
-        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
-                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
-
-        if (mSecureProfile) {
-            String summaryHideEntry = getString(
-                    R.string.lock_screen_notifications_summary_hide_profile);
-            String summaryHideEntryValue = Integer.toString(
-                    R.string.lock_screen_notifications_summary_hide_profile);
-            entries.add(summaryHideEntry);
-            values.add(summaryHideEntryValue);
-            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
-                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
-        }
-
-        mLockscreenProfile.setOnPreClickListener(
-                (Preference p) -> Utils.startQuietModeDialogIfNecessary(mContext,
-                        UserManager.get(mContext),
-                        mProfileChallengeUserId)
-        );
-
-        mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()]));
-        mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
-        updateLockscreenNotificationsForProfile();
-        if (mLockscreenProfile.getEntries().length > 1) {
-            mLockscreenProfile.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
-                @Override
-                public boolean onPreferenceChange(Preference preference, Object newValue) {
-                    final int val = Integer.parseInt((String) newValue);
-                    if (val == mLockscreenSelectedValueProfile) {
-                        return false;
-                    }
-                    final boolean enabled =
-                            val != R.string.lock_screen_notifications_summary_disable_profile;
-                    final boolean show =
-                            val == R.string.lock_screen_notifications_summary_show_profile;
-                    Settings.Secure.putIntForUser(getContentResolver(),
-                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
-                            show ? 1 : 0, mProfileChallengeUserId);
-                    Settings.Secure.putIntForUser(getContentResolver(),
-                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                            enabled ? 1 : 0, mProfileChallengeUserId);
-                    mLockscreenSelectedValueProfile = val;
-                    return true;
-                }
-            });
-        } else {
-            // There is one or less option for the user, disable the drop down.
-            mLockscreenProfile.setEnabled(false);
-        }
-    }
-
-    private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
-            CharSequence entryValue, int keyguardNotificationFeatures) {
-        EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
-                mContext, keyguardNotificationFeatures, UserHandle.myUserId());
-        if (admin != null && mLockscreen != null) {
-            RestrictedDropDownPreference.RestrictedItem item =
-                    new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
-            mLockscreen.addRestrictedItem(item);
-        }
-        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
-            EnforcedAdmin profileAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
-                    mContext, keyguardNotificationFeatures, mProfileChallengeUserId);
-            if (profileAdmin != null && mLockscreenProfile != null) {
-                RestrictedDropDownPreference.RestrictedItem item =
-                        new RestrictedDropDownPreference.RestrictedItem(
-                                entry, entryValue, profileAdmin);
-                mLockscreenProfile.addRestrictedItem(item);
-            }
-        }
-    }
-
-    private void updateLockscreenNotifications() {
-        if (mLockscreen == null) {
-            return;
-        }
-        final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId());
-        final boolean allowPrivate = !mSecure
-                || getLockscreenAllowPrivateNotifications(UserHandle.myUserId());
-        mLockscreenSelectedValue = !enabled ? R.string.lock_screen_notifications_summary_disable :
-                allowPrivate ? R.string.lock_screen_notifications_summary_show :
-                R.string.lock_screen_notifications_summary_hide;
-        mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
-    }
-
-    private void updateLockscreenNotificationsForProfile() {
-        if (mProfileChallengeUserId == UserHandle.USER_NULL) {
-            return;
-        }
-        if (mLockscreenProfile == null) {
-            return;
-        }
-        final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId);
-        final boolean allowPrivate = !mSecureProfile
-                || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId);
-        mLockscreenSelectedValueProfile = !enabled
-                ? R.string.lock_screen_notifications_summary_disable_profile
-                        : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile
-                                : R.string.lock_screen_notifications_summary_hide_profile);
-        mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
-    }
-
-    private boolean getLockscreenNotificationsEnabled(int userId) {
-        return Settings.Secure.getIntForUser(getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
-    }
-
-    private boolean getLockscreenAllowPrivateNotifications(int userId) {
-        return Settings.Secure.getIntForUser(getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
-    }
-
-
-    // === Callbacks ===
-
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri NOTIFICATION_LIGHT_PULSE_URI =
-                Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
-        private final Uri LOCK_SCREEN_PRIVATE_URI =
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
-        private final Uri LOCK_SCREEN_SHOW_URI =
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
-
-        public SettingsObserver() {
-            super(new Handler());
-        }
-
-        public void register(boolean register) {
-            final ContentResolver cr = getContentResolver();
-            if (register) {
-                cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this);
-                cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this);
-                cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this);
-            } else {
-                cr.unregisterContentObserver(this);
-            }
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            super.onChange(selfChange, uri);
-            if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
-                updatePulse();
-            }
-            if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) {
-                updateLockscreenNotifications();
-                if (mProfileChallengeUserId != UserHandle.USER_NULL) {
-                    updateLockscreenNotificationsForProfile();
-                }
-            }
-        }
+    @Override
+    protected List<PreferenceController> getPreferenceControllers(Context context) {
+        final List<PreferenceController> controllers = new ArrayList<>();
+        final PulseNotificationPreferenceController pulseController =
+                new PulseNotificationPreferenceController(context);
+        mLockScreenNotificationController = new LockScreenNotificationPreferenceController(context);
+        getLifecycle().addObserver(pulseController);
+        getLifecycle().addObserver(mLockScreenNotificationController);
+        controllers.add(pulseController);
+        controllers.add(mLockScreenNotificationController);
+        return controllers;
     }
 }
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
new file mode 100644
index 0000000..f349a84
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2016 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.notification;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.util.Log;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settingslib.RestrictedLockUtils;
+
+import java.util.ArrayList;
+
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
+public class LockScreenNotificationPreferenceController extends PreferenceController implements
+        Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+    private static final String TAG = "LockScreenNotifPref";
+    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications";
+    private static final String KEY_LOCK_SCREEN_PROFILE_HEADER =
+            "lock_screen_notifications_profile_header";
+    private static final String KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS =
+            "lock_screen_notifications_profile";
+
+    private RestrictedDropDownPreference mLockscreen;
+    private RestrictedDropDownPreference mLockscreenProfile;
+
+    private final int mProfileChallengeUserId;
+    private final boolean mSecure;
+    private final boolean mSecureProfile;
+
+    private SettingObserver mSettingObserver;
+    private int mLockscreenSelectedValue;
+    private int mLockscreenSelectedValueProfile;
+
+    public LockScreenNotificationPreferenceController(Context context) {
+        super(context);
+        mProfileChallengeUserId = Utils.getManagedProfileId(
+                UserManager.get(context), UserHandle.myUserId());
+        final LockPatternUtils utils = new LockPatternUtils(context);
+        final boolean isUnified =
+                !utils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
+        mSecure = utils.isSecure(UserHandle.myUserId());
+        mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
+                && (utils.isSecure(mProfileChallengeUserId) || (isUnified && mSecure));
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mLockscreen =
+                (RestrictedDropDownPreference) screen.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS);
+        if (mLockscreen == null) {
+            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS);
+            return;
+        }
+        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
+            mLockscreenProfile = (RestrictedDropDownPreference) screen.findPreference(
+                    KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
+        } else {
+            removePreference(screen, KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
+            removePreference(screen, KEY_LOCK_SCREEN_PROFILE_HEADER);
+        }
+        mSettingObserver = new SettingObserver();
+        initLockScreenNotificationPrefDisplay();
+        initLockscreenNotificationPrefForProfile();
+    }
+
+    private void initLockScreenNotificationPrefDisplay() {
+        ArrayList<CharSequence> entries = new ArrayList<>();
+        ArrayList<CharSequence> values = new ArrayList<>();
+        entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable));
+        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable));
+
+        String summaryShowEntry =
+                mContext.getString(R.string.lock_screen_notifications_summary_show);
+        String summaryShowEntryValue =
+                Integer.toString(R.string.lock_screen_notifications_summary_show);
+        entries.add(summaryShowEntry);
+        values.add(summaryShowEntryValue);
+        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+        if (mSecure) {
+            String summaryHideEntry =
+                    mContext.getString(R.string.lock_screen_notifications_summary_hide);
+            String summaryHideEntryValue =
+                    Integer.toString(R.string.lock_screen_notifications_summary_hide);
+            entries.add(summaryHideEntry);
+            values.add(summaryHideEntryValue);
+            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
+                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+        }
+
+        mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()]));
+        mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()]));
+        updateLockscreenNotifications();
+
+        if (mLockscreen.getEntries().length > 1) {
+            mLockscreen.setOnPreferenceChangeListener(this);
+        } else {
+            // There is one or less option for the user, disable the drop down.
+            mLockscreen.setEnabled(false);
+        }
+    }
+
+    private void initLockscreenNotificationPrefForProfile() {
+        if (mLockscreenProfile == null) {
+            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
+            return;
+        }
+        ArrayList<CharSequence> entries = new ArrayList<>();
+        ArrayList<CharSequence> values = new ArrayList<>();
+        entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable_profile));
+        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile));
+
+        String summaryShowEntry = mContext.getString(
+                R.string.lock_screen_notifications_summary_show_profile);
+        String summaryShowEntryValue = Integer.toString(
+                R.string.lock_screen_notifications_summary_show_profile);
+        entries.add(summaryShowEntry);
+        values.add(summaryShowEntryValue);
+        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+        if (mSecureProfile) {
+            String summaryHideEntry = mContext.getString(
+                    R.string.lock_screen_notifications_summary_hide_profile);
+            String summaryHideEntryValue = Integer.toString(
+                    R.string.lock_screen_notifications_summary_hide_profile);
+            entries.add(summaryHideEntry);
+            values.add(summaryHideEntryValue);
+            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
+                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+        }
+        mLockscreenProfile.setOnPreClickListener(
+                (Preference p) -> Utils.startQuietModeDialogIfNecessary(mContext,
+                        UserManager.get(mContext), mProfileChallengeUserId)
+        );
+
+        mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()]));
+        mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
+        updateLockscreenNotificationsForProfile();
+        if (mLockscreenProfile.getEntries().length > 1) {
+            mLockscreenProfile.setOnPreferenceChangeListener(this);
+        } else {
+            // There is one or less option for the user, disable the drop down.
+            mLockscreenProfile.setEnabled(false);
+        }
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return null;
+    }
+
+    @Override
+    protected boolean isAvailable() {
+        return false;
+    }
+
+    @Override
+    public void onResume() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        switch (preference.getKey()) {
+            case KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS: {
+                final int val = Integer.parseInt((String) newValue);
+                if (val == mLockscreenSelectedValueProfile) {
+                    return false;
+                }
+                final boolean enabled =
+                        val != R.string.lock_screen_notifications_summary_disable_profile;
+                final boolean show =
+                        val == R.string.lock_screen_notifications_summary_show_profile;
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                        show ? 1 : 0, mProfileChallengeUserId);
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                        enabled ? 1 : 0, mProfileChallengeUserId);
+                mLockscreenSelectedValueProfile = val;
+                return true;
+            }
+            case KEY_LOCK_SCREEN_NOTIFICATIONS: {
+                final int val = Integer.parseInt((String) newValue);
+                if (val == mLockscreenSelectedValue) {
+                    return false;
+                }
+                final boolean enabled =
+                        val != R.string.lock_screen_notifications_summary_disable;
+                final boolean show = val == R.string.lock_screen_notifications_summary_show;
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
+                mLockscreenSelectedValue = val;
+                return true;
+            }
+            default:
+                return false;
+        }
+    }
+
+    private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
+            CharSequence entryValue, int keyguardNotificationFeatures) {
+        RestrictedLockUtils.EnforcedAdmin admin =
+                RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+                        mContext, keyguardNotificationFeatures, UserHandle.myUserId());
+        if (admin != null && mLockscreen != null) {
+            RestrictedDropDownPreference.RestrictedItem item =
+                    new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin);
+            mLockscreen.addRestrictedItem(item);
+        }
+        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
+            RestrictedLockUtils.EnforcedAdmin profileAdmin =
+                    RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
+                            mContext, keyguardNotificationFeatures, mProfileChallengeUserId);
+            if (profileAdmin != null && mLockscreenProfile != null) {
+                RestrictedDropDownPreference.RestrictedItem item =
+                        new RestrictedDropDownPreference.RestrictedItem(
+                                entry, entryValue, profileAdmin);
+                mLockscreenProfile.addRestrictedItem(item);
+            }
+        }
+    }
+
+    private void updateLockscreenNotifications() {
+        if (mLockscreen == null) {
+            return;
+        }
+        final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId());
+        final boolean allowPrivate = !mSecure
+                || getLockscreenAllowPrivateNotifications(UserHandle.myUserId());
+        mLockscreenSelectedValue = !enabled ? R.string.lock_screen_notifications_summary_disable :
+                allowPrivate ? R.string.lock_screen_notifications_summary_show :
+                        R.string.lock_screen_notifications_summary_hide;
+        mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
+    }
+
+    private void updateLockscreenNotificationsForProfile() {
+        if (mProfileChallengeUserId == UserHandle.USER_NULL) {
+            return;
+        }
+        if (mLockscreenProfile == null) {
+            return;
+        }
+        final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId);
+        final boolean allowPrivate = !mSecureProfile
+                || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId);
+        mLockscreenSelectedValueProfile = !enabled
+                ? R.string.lock_screen_notifications_summary_disable_profile
+                : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile
+                        : R.string.lock_screen_notifications_summary_hide_profile);
+        mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
+    }
+
+    private boolean getLockscreenNotificationsEnabled(int userId) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
+    }
+
+    private boolean getLockscreenAllowPrivateNotifications(int userId) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
+    }
+
+    class SettingObserver extends ContentObserver {
+
+        private final Uri LOCK_SCREEN_PRIVATE_URI =
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+        private final Uri LOCK_SCREEN_SHOW_URI =
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
+
+        public SettingObserver() {
+            super(new Handler());
+        }
+
+        public void register(ContentResolver cr, boolean register) {
+            if (register) {
+                cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this);
+                cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this);
+            } else {
+                cr.unregisterContentObserver(this);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) {
+                updateLockscreenNotifications();
+                if (mProfileChallengeUserId != UserHandle.USER_NULL) {
+                    updateLockscreenNotificationsForProfile();
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/PulseNotificationPreferenceController.java b/src/com/android/settings/notification/PulseNotificationPreferenceController.java
new file mode 100644
index 0000000..03832e5
--- /dev/null
+++ b/src/com/android/settings/notification/PulseNotificationPreferenceController.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 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.notification;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.TwoStatePreference;
+import android.util.Log;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
+
+public class PulseNotificationPreferenceController extends PreferenceController implements
+        Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+    private static final String TAG = "PulseNotifPrefContr";
+    private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
+    private SettingObserver mSettingObserver;
+
+    public PulseNotificationPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        Preference preference = screen.findPreference(KEY_NOTIFICATION_PULSE);
+        if (preference != null) {
+            mSettingObserver = new SettingObserver(preference);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(mContext.getContentResolver(), true /* register */);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(mContext.getContentResolver(), false /* register */);
+        }
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_NOTIFICATION_PULSE;
+    }
+
+    @Override
+    protected boolean isAvailable() {
+        return mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        try {
+            final boolean checked = Settings.System.getInt(mContext.getContentResolver(),
+                    NOTIFICATION_LIGHT_PULSE) == 1;
+            ((TwoStatePreference) preference).setChecked(checked);
+        } catch (Settings.SettingNotFoundException snfe) {
+            Log.e(TAG, NOTIFICATION_LIGHT_PULSE + " not found");
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean val = (Boolean) newValue;
+        return Settings.System.putInt(mContext.getContentResolver(),
+                NOTIFICATION_LIGHT_PULSE, val ? 1 : 0);
+    }
+
+    class SettingObserver extends ContentObserver {
+
+        private final Uri NOTIFICATION_LIGHT_PULSE_URI =
+                Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
+
+        private final Preference mPreference;
+
+        public SettingObserver(Preference preference) {
+            super(new Handler());
+            mPreference = preference;
+        }
+
+        public void register(ContentResolver cr, boolean register) {
+            if (register) {
+                cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this);
+            } else {
+                cr.unregisterContentObserver(this);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
+                updateState(mPreference);
+            }
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 8fc290e..6d11041 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -154,7 +154,7 @@
         mTestFragment.bindPreferenceToTile(mContext, preference, tile, "123");
 
         assertThat(preference.getFragment()).isNull();
-        assertThat(preference.getIntent()).isNotNull();
+        assertThat(preference.getOnPreferenceClickListener()).isNotNull();
         assertThat(preference.getOrder()).isEqualTo(-tile.priority);
     }
 
diff --git a/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java
new file mode 100644
index 0000000..4eb33e9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/PulseNotificationPreferenceControllerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 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.notification;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.TwoStatePreference;
+
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PulseNotificationPreferenceControllerTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private PreferenceScreen mScreen;
+
+    private PulseNotificationPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new PulseNotificationPreferenceController(mContext);
+    }
+
+    @Test
+    public void display_configIsTrue_shouldDisplay() {
+        when(mContext.getResources().
+                getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
+                .thenReturn(true);
+        mController.displayPreference(mScreen);
+
+        verify(mScreen, never()).removePreference(any(Preference.class));
+    }
+
+    @Test
+    public void display_configIsFalse_shouldNotDisplay() {
+        when(mContext.getResources().
+                getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
+                .thenReturn(false);
+        when(mScreen.findPreference(mController.getPreferenceKey()))
+                .thenReturn(mock(Preference.class));
+
+        mController.displayPreference(mScreen);
+
+        verify(mScreen).removePreference(any(Preference.class));
+    }
+
+    @Test
+    public void updateState_preferenceSetCheckedWhenSettingIsOn() {
+        final TwoStatePreference preference = mock(TwoStatePreference.class);
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        Settings.System.putInt(context.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 1);
+
+        mController = new PulseNotificationPreferenceController(context);
+        mController.updateState(preference);
+
+        verify(preference).setChecked(true);
+    }
+
+    @Test
+    public void updateState_preferenceSetUncheckedWhenSettingIsOff() {
+        final TwoStatePreference preference = mock(TwoStatePreference.class);
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        Settings.System.putInt(context.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 0);
+
+        mController = new PulseNotificationPreferenceController(context);
+        mController.updateState(preference);
+
+        verify(preference).setChecked(false);
+    }
+}