diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 226c4401347..a71821f8614 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -859,7 +859,7 @@ - + - + - @@ -2340,22 +2340,18 @@ - - - - + android:value="com.android.settings.notification.ConfigureNotificationSettings" /> - + android:exported="true"> @@ -2365,20 +2361,26 @@ + + + + + + android:value="com.android.settings.notification.SoundSettings" /> - + + android:targetActivity="Settings$SoundSettingsActivity"> + android:value="com.android.settings.notification.SoundSettings" /> + + + + diff --git a/res/menu/zen_settings_menu.xml b/res/menu/zen_settings_menu.xml new file mode 100644 index 00000000000..ff28403658e --- /dev/null +++ b/res/menu/zen_settings_menu.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 28113da228e..ecc465ec676 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5888,7 +5888,7 @@ reset restore factory wipe delete restore clear remove printer - speaker beep + speaker beep dont don\u2019t disturb interrupt interruption break RAM nearby location history reporting @@ -5929,78 +5929,117 @@ + + Ringer volume at %1$s - - Sound & notification - - + Media volume - + Alarm volume - + Ring volume - + Notification volume - - @*android:string/zen_mode_feature_name - - - Priority only allows - - - Automatic rules - - - Priority only - - - Alarms only - - - Total silence - - - %1$s: %2$s - - - Visual interruptions - - + Phone ringtone - + Default notification ringtone - + Also vibrate for calls - - Notification + + Other sounds - + + Dial pad tones + + + Screen locking sounds + + + Charging sounds + + + Docking sounds + + + Touch sounds + + + Vibrate on touch + + + Dock speaker plays + + + All audio + + + Media audio only + + + Silent + + + Alert + + + Vibrate + + + @*android:string/zen_mode_feature_name + + + Priority only allows + + + Automatic rules + + + Priority only + + + Alarms only + + + Total silence + + + %1$s: %2$s + + + Visual interruptions + + + + Configure notifications + + Advanced - + Pulse notification light - + When device is locked - Show all notification content - Hide sensitive notification content - Don\u2019t show notifications at all @@ -6010,50 +6049,13 @@ Notifications - - App notifications + + Notifications Topic notifications - - Other sounds - - Dial pad tones - - - Screen locking sounds - - - Charging sounds - - - Docking sounds - - - Touch sounds - - - Vibrate on touch - - - Dock speaker plays - - - All audio - - - Media audio only - - - Silent - - - Alert - - - Vibrate Notification access @@ -6320,9 +6322,6 @@ Prevent notifications silenced by Do Not Disturb from causing the light to pulse - - App notifications - Notification settings diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml new file mode 100644 index 00000000000..aa15f06c598 --- /dev/null +++ b/res/xml/configure_notification_settings.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/notification_settings.xml b/res/xml/sound_settings.xml similarity index 63% rename from res/xml/notification_settings.xml rename to res/xml/sound_settings.xml index 43fd116592f..652310ffdc1 100644 --- a/res/xml/notification_settings.xml +++ b/res/xml/sound_settings.xml @@ -1,5 +1,5 @@ - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml index 96f26ac3d25..2d25ed52e8f 100644 --- a/res/xml/wireless_settings.xml +++ b/res/xml/wireless_settings.xml @@ -81,13 +81,4 @@ android:key="proxy_settings" android:title="@string/proxy_settings_title" /> - - - - diff --git a/src/com/android/settings/InstrumentedFragment.java b/src/com/android/settings/InstrumentedFragment.java index 5453d521608..80e11317a93 100644 --- a/src/com/android/settings/InstrumentedFragment.java +++ b/src/com/android/settings/InstrumentedFragment.java @@ -29,6 +29,8 @@ public abstract class InstrumentedFragment extends PreferenceFragment { public static final int UNDECLARED = 100000; public static final int ACCESSIBILITY_TOGGLE_AUTOCLICK = UNDECLARED + 1; + public static final int SOUND = UNDECLARED + 2; + public static final int CONFIGURE_NOTIFICATION = UNDECLARED + 3; /** * Declare the view of this category. diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 46d24ae87a8..4380d1e52f2 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -105,7 +105,8 @@ public class Settings extends SettingsActivity { public static class ZenModeEventRuleSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeExternalRuleSettingsActivity extends SettingsActivity { /* empty */ } public static class ZenModeVisualInterruptionSettingsActivity extends SettingsActivity { /* empty */} - public static class NotificationSettingsActivity extends SettingsActivity { /* empty */ } + public static class SoundSettingsActivity extends SettingsActivity { /* empty */ } + public static class ConfigureNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class NotificationAppListActivity extends SettingsActivity { /* empty */ } public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ } public static class OtherSoundSettingsActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index fd4a493fadb..809a740c30f 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -82,8 +82,9 @@ import com.android.settings.location.LocationSettings; import com.android.settings.nfc.AndroidBeam; import com.android.settings.nfc.PaymentSettings; import com.android.settings.notification.AppNotificationSettings; +import com.android.settings.notification.ConfigureNotificationSettings; import com.android.settings.notification.NotificationAccessSettings; -import com.android.settings.notification.NotificationSettings; +import com.android.settings.notification.SoundSettings; import com.android.settings.notification.NotificationStation; import com.android.settings.notification.OtherSoundSettings; import com.android.settings.notification.ZenAccessSettings; @@ -211,7 +212,7 @@ public class SettingsActivity extends SettingsDrawerActivity Settings.WirelessSettingsActivity.class.getName(), //device_section Settings.HomeSettingsActivity.class.getName(), - Settings.NotificationSettingsActivity.class.getName(), + Settings.SoundSettingsActivity.class.getName(), Settings.DisplaySettingsActivity.class.getName(), Settings.StorageSettingsActivity.class.getName(), Settings.ManageApplicationsActivity.class.getName(), @@ -284,7 +285,8 @@ public class SettingsActivity extends SettingsDrawerActivity PaymentSettings.class.getName(), KeyboardLayoutPickerFragment.class.getName(), ZenModeSettings.class.getName(), - NotificationSettings.class.getName(), + SoundSettings.class.getName(), + ConfigureNotificationSettings.class.getName(), ChooseLockPassword.ChooseLockPasswordFragment.class.getName(), ChooseLockPattern.ChooseLockPatternFragment.class.getName(), InstalledAppDetails.class.getName(), diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 35ae4275eb3..a01e18d8c11 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -67,6 +67,7 @@ import com.android.settings.dashboard.SummaryLoader; import com.android.settings.fuelgauge.HighPowerDetail; import com.android.settings.fuelgauge.PowerWhitelistBackend; import com.android.settings.notification.AppNotificationSettings; +import com.android.settings.notification.ConfigureNotificationSettings; import com.android.settings.notification.NotificationBackend; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settingslib.applications.ApplicationsState; @@ -523,7 +524,8 @@ public class ManageApplications extends InstrumentedFragment if (mOptionsMenu == null) { return; } - mOptionsMenu.findItem(R.id.advanced).setVisible(mListType == LIST_TYPE_MAIN); + mOptionsMenu.findItem(R.id.advanced).setVisible( + mListType == LIST_TYPE_MAIN || mListType == LIST_TYPE_NOTIFICATION); mOptionsMenu.findItem(R.id.sort_order_alpha).setVisible(mListType == LIST_TYPE_STORAGE && mSortOrder != R.id.sort_order_alpha); @@ -556,9 +558,15 @@ public class ManageApplications extends InstrumentedFragment mResetAppsHelper.buildResetDialog(); return true; case R.id.advanced: - ((SettingsActivity) getActivity()).startPreferencePanel( - AdvancedAppSettings.class.getName(), null, R.string.configure_apps, - null, this, ADVANCED_SETTINGS); + if (mListType == LIST_TYPE_NOTIFICATION) { + ((SettingsActivity) getActivity()).startPreferencePanel( + ConfigureNotificationSettings.class.getName(), null, + R.string.configure_notification_settings, null, this, ADVANCED_SETTINGS); + } else { + ((SettingsActivity) getActivity()).startPreferencePanel( + AdvancedAppSettings.class.getName(), null, R.string.configure_apps, + null, this, ADVANCED_SETTINGS); + } return true; default: // Handle the home button diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java new file mode 100644 index 00000000000..4b438f09e78 --- /dev/null +++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java @@ -0,0 +1,250 @@ +/** + * Copyright (C) 2015 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 com.android.internal.widget.LockPatternUtils; +import com.android.settings.DropDownPreference; +import com.android.settings.InstrumentedFragment; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; + +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.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 java.util.ArrayList; + +public class ConfigureNotificationSettings extends SettingsPreferenceFragment { + 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 final SettingsObserver mSettingsObserver = new SettingsObserver(); + + private Context mContext; + + private TwoStatePreference mNotificationPulse; + private DropDownPreference mLockscreen; + private boolean mSecure; + private int mLockscreenSelectedValue; + + @Override + protected int getMetricsCategory() { + return InstrumentedFragment.CONFIGURE_NOTIFICATION; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mContext = getActivity(); + mSecure = new LockPatternUtils(getActivity()).isSecure(UserHandle.myUserId()); + + addPreferencesFromResource(R.xml.configure_notification_settings); + + initPulse(); + initLockscreenNotifications(); + + } + + @Override + public void onResume() { + super.onResume(); + mSettingsObserver.register(true); + } + + @Override + public void onPause() { + super.onPause(); + mSettingsObserver.register(false); + } + + // === 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"); + } + } + + // === Lockscreen (public / private) notifications === + + private void initLockscreenNotifications() { + mLockscreen = (DropDownPreference) getPreferenceScreen().findPreference( + KEY_LOCK_SCREEN_NOTIFICATIONS); + if (mLockscreen == null) { + Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS); + return; + } + + boolean isSecureNotificationsDisabled = isSecureNotificationsDisabled(); + boolean isUnredactedNotificationsDisabled = isUnredactedNotificationsDisabled(); + ArrayList entries = new ArrayList<>(); + ArrayList values = new ArrayList<>(); + if (!isSecureNotificationsDisabled && !isUnredactedNotificationsDisabled) { + entries.add(getString(R.string.lock_screen_notifications_summary_show)); + values.add(Integer.toString(R.string.lock_screen_notifications_summary_show)); + } + if (mSecure && !isSecureNotificationsDisabled) { + entries.add(getString(R.string.lock_screen_notifications_summary_hide)); + values.add(Integer.toString(R.string.lock_screen_notifications_summary_hide)); + } + entries.add(getString(R.string.lock_screen_notifications_summary_disable)); + values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable)); + + 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); + } + } + + private boolean isSecureNotificationsDisabled() { + final DevicePolicyManager dpm = + (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); + return dpm != null && (dpm.getKeyguardDisabledFeatures(null) + & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) != 0; + } + + private boolean isUnredactedNotificationsDisabled() { + final DevicePolicyManager dpm = + (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); + return dpm != null && (dpm.getKeyguardDisabledFeatures(null) + & DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS) != 0; + } + + private void updateLockscreenNotifications() { + if (mLockscreen == null) { + return; + } + final boolean enabled = getLockscreenNotificationsEnabled(); + final boolean allowPrivate = !mSecure || getLockscreenAllowPrivateNotifications(); + 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 boolean getLockscreenNotificationsEnabled() { + return Settings.Secure.getInt(getContentResolver(), + Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0; + } + + private boolean getLockscreenAllowPrivateNotifications() { + return Settings.Secure.getInt(getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 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(); + } + } + } +} diff --git a/src/com/android/settings/notification/NotificationSettings.java b/src/com/android/settings/notification/SoundSettings.java similarity index 64% rename from src/com/android/settings/notification/NotificationSettings.java rename to src/com/android/settings/notification/SoundSettings.java index 46935d0271c..9e2752829d0 100644 --- a/src/com/android/settings/notification/NotificationSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -16,8 +16,8 @@ package com.android.settings.notification; +import android.app.Activity; import android.app.NotificationManager; -import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -37,7 +37,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; import android.preference.SeekBarVolumizer; @@ -47,29 +46,27 @@ import android.provider.SearchIndexableResource; import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; -import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.TwoStatePreference; import android.util.Log; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.widget.LockPatternUtils; -import com.android.settings.DropDownPreference; +import com.android.settings.InstrumentedFragment; import com.android.settings.R; import com.android.settings.RingtonePreference; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; +import com.android.settings.dashboard.SummaryLoader; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; +import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; -public class NotificationSettings extends SettingsPreferenceFragment implements Indexable { - private static final String TAG = "NotificationSettings"; +public class SoundSettings extends SettingsPreferenceFragment implements Indexable { + private static final String TAG = "SoundSettings"; - private static final String KEY_SOUND = "sound"; private static final String KEY_MEDIA_VOLUME = "media_volume"; private static final String KEY_ALARM_VOLUME = "alarm_volume"; private static final String KEY_RING_VOLUME = "ring_volume"; @@ -78,11 +75,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements private static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone"; private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing"; private static final String KEY_WIFI_DISPLAY = "wifi_display"; - private static final String KEY_NOTIFICATION = "notification"; - 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_NOTIFICATION_ACCESS = "manage_notification_access"; - private static final String KEY_ZEN_ACCESS = "manage_zen_access"; private static final String KEY_ZEN_MODE = "zen_mode"; private static final String[] RESTRICTED_KEYS = { @@ -90,7 +82,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements KEY_ALARM_VOLUME, KEY_RING_VOLUME, KEY_NOTIFICATION_VOLUME, - KEY_ZEN_ACCESS, KEY_ZEN_MODE, }; @@ -103,7 +94,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements private final ArrayList mVolumePrefs = new ArrayList<>(); private Context mContext; - private PackageManager mPM; private boolean mVoiceCapable; private Vibrator mVibrator; private AudioManager mAudioManager; @@ -112,12 +102,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements private Preference mPhoneRingtonePreference; private Preference mNotificationRingtonePreference; private TwoStatePreference mVibrateWhenRinging; - private TwoStatePreference mNotificationPulse; - private DropDownPreference mLockscreen; - private Preference mNotificationAccess; - private Preference mZenAccess; - private boolean mSecure; - private int mLockscreenSelectedValue; private ComponentName mSuppressor; private int mRingerMode = -1; @@ -126,17 +110,15 @@ public class NotificationSettings extends SettingsPreferenceFragment implements @Override protected int getMetricsCategory() { - return MetricsLogger.NOTIFICATION; + return InstrumentedFragment.SOUND; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getActivity(); - mPM = mContext.getPackageManager(); mUserManager = UserManager.get(getContext()); mVoiceCapable = Utils.isVoiceCapable(mContext); - mSecure = new LockPatternUtils(getActivity()).isSecure(UserHandle.myUserId()); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); mVibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE); @@ -144,9 +126,8 @@ public class NotificationSettings extends SettingsPreferenceFragment implements mVibrator = null; } - addPreferencesFromResource(R.xml.notification_settings); + addPreferencesFromResource(R.xml.sound_settings); - final PreferenceCategory sound = (PreferenceCategory) findPreference(KEY_SOUND); initVolumePreference(KEY_MEDIA_VOLUME, AudioManager.STREAM_MUSIC, com.android.internal.R.drawable.ic_audio_media_mute); initVolumePreference(KEY_ALARM_VOLUME, AudioManager.STREAM_ALARM, @@ -155,25 +136,15 @@ public class NotificationSettings extends SettingsPreferenceFragment implements mRingOrNotificationPreference = initVolumePreference(KEY_RING_VOLUME, AudioManager.STREAM_RING, com.android.internal.R.drawable.ic_audio_ring_notif_mute); - sound.removePreference(sound.findPreference(KEY_NOTIFICATION_VOLUME)); + removePreference(KEY_NOTIFICATION_VOLUME); } else { mRingOrNotificationPreference = initVolumePreference(KEY_NOTIFICATION_VOLUME, AudioManager.STREAM_NOTIFICATION, com.android.internal.R.drawable.ic_audio_ring_notif_mute); - sound.removePreference(sound.findPreference(KEY_RING_VOLUME)); + removePreference(KEY_RING_VOLUME); } - initRingtones(sound); - initVibrateWhenRinging(sound); - - final PreferenceCategory notification = (PreferenceCategory) - findPreference(KEY_NOTIFICATION); - initPulse(notification); - initLockscreenNotifications(notification); - - mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS); - refreshNotificationListeners(); - mZenAccess = findPreference(KEY_ZEN_ACCESS); - refreshZenAccess(); + initRingtones(); + initVibrateWhenRinging(); updateRingerMode(); updateEffectsSuppressor(); } @@ -181,8 +152,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements @Override public void onResume() { super.onResume(); - refreshNotificationListeners(); - refreshZenAccess(); lookupRingtoneNames(); mSettingsObserver.register(true); mReceiver.register(true); @@ -323,13 +292,14 @@ public class NotificationSettings extends SettingsPreferenceFragment implements // === Phone & notification ringtone === - private void initRingtones(PreferenceCategory root) { - mPhoneRingtonePreference = root.findPreference(KEY_PHONE_RINGTONE); + private void initRingtones() { + mPhoneRingtonePreference = getPreferenceScreen().findPreference(KEY_PHONE_RINGTONE); if (mPhoneRingtonePreference != null && !mVoiceCapable) { - root.removePreference(mPhoneRingtonePreference); + getPreferenceScreen().removePreference(mPhoneRingtonePreference); mPhoneRingtonePreference = null; } - mNotificationRingtonePreference = root.findPreference(KEY_NOTIFICATION_RINGTONE); + mNotificationRingtonePreference = + getPreferenceScreen().findPreference(KEY_NOTIFICATION_RINGTONE); } private void lookupRingtoneNames() { @@ -397,14 +367,15 @@ public class NotificationSettings extends SettingsPreferenceFragment implements // === Vibrate when ringing === - private void initVibrateWhenRinging(PreferenceCategory root) { - mVibrateWhenRinging = (TwoStatePreference) root.findPreference(KEY_VIBRATE_WHEN_RINGING); + private void initVibrateWhenRinging() { + mVibrateWhenRinging = + (TwoStatePreference) getPreferenceScreen().findPreference(KEY_VIBRATE_WHEN_RINGING); if (mVibrateWhenRinging == null) { Log.i(TAG, "Preference not found: " + KEY_VIBRATE_WHEN_RINGING); return; } if (!mVoiceCapable) { - root.removePreference(mVibrateWhenRinging); + getPreferenceScreen().removePreference(mVibrateWhenRinging); mVibrateWhenRinging = null; return; } @@ -427,164 +398,11 @@ public class NotificationSettings extends SettingsPreferenceFragment implements Settings.System.VIBRATE_WHEN_RINGING, 0) != 0); } - // === Pulse notification light === - - private void initPulse(PreferenceCategory parent) { - mNotificationPulse = (TwoStatePreference) parent.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)) { - parent.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"); - } - } - - // === Lockscreen (public / private) notifications === - - private void initLockscreenNotifications(PreferenceCategory parent) { - mLockscreen = (DropDownPreference) parent.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS); - if (mLockscreen == null) { - Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS); - return; - } - - boolean isSecureNotificationsDisabled = isSecureNotificationsDisabled(); - boolean isUnredactedNotificationsDisabled = isUnredactedNotificationsDisabled(); - ArrayList entries = new ArrayList<>(); - ArrayList values = new ArrayList<>(); - if (!isSecureNotificationsDisabled && !isUnredactedNotificationsDisabled) { - entries.add(getString(R.string.lock_screen_notifications_summary_show)); - values.add(Integer.toString(R.string.lock_screen_notifications_summary_show)); - } - if (mSecure && !isSecureNotificationsDisabled) { - entries.add(getString(R.string.lock_screen_notifications_summary_hide)); - values.add(Integer.toString(R.string.lock_screen_notifications_summary_hide)); - } - entries.add(getString(R.string.lock_screen_notifications_summary_disable)); - values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable)); - - 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); - } - } - - private boolean isSecureNotificationsDisabled() { - final DevicePolicyManager dpm = - (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); - return dpm != null && (dpm.getKeyguardDisabledFeatures(null) - & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) != 0; - } - - private boolean isUnredactedNotificationsDisabled() { - final DevicePolicyManager dpm = - (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); - return dpm != null && (dpm.getKeyguardDisabledFeatures(null) - & DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS) != 0; - } - - private void updateLockscreenNotifications() { - if (mLockscreen == null) { - return; - } - final boolean enabled = getLockscreenNotificationsEnabled(); - final boolean allowPrivate = !mSecure || getLockscreenAllowPrivateNotifications(); - 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 boolean getLockscreenNotificationsEnabled() { - return Settings.Secure.getInt(getContentResolver(), - Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0; - } - - private boolean getLockscreenAllowPrivateNotifications() { - return Settings.Secure.getInt(getContentResolver(), - Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0; - } - - // === Notification listeners === - - private void refreshNotificationListeners() { - if (mNotificationAccess != null) { - final int n = NotificationAccessSettings.getEnabledListenersCount(mContext); - 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))); - } - } - } - - // === Zen access === - - private void refreshZenAccess() { - // noop for now - } - // === Callbacks === private final class SettingsObserver extends ContentObserver { private final Uri VIBRATE_WHEN_RINGING_URI = Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING); - 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(mHandler); @@ -594,9 +412,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements final ContentResolver cr = getContentResolver(); if (register) { cr.registerContentObserver(VIBRATE_WHEN_RINGING_URI, false, this); - 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); } @@ -608,12 +423,6 @@ public class NotificationSettings extends SettingsPreferenceFragment implements if (VIBRATE_WHEN_RINGING_URI.equals(uri)) { updateVibrateWhenRinging(); } - if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { - updatePulse(); - } - if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) { - updateLockscreenNotifications(); - } } } @@ -677,6 +486,57 @@ public class NotificationSettings extends SettingsPreferenceFragment implements } } + // === Summary === + + private static class SummaryProvider extends BroadcastReceiver + implements SummaryLoader.SummaryProvider { + + private final Context mContext; + private final AudioManager mAudioManager; + private final SummaryLoader mSummaryLoader; + private final int maxVolume; + + public SummaryProvider(Context context, SummaryLoader summaryLoader) { + mContext = context; + mSummaryLoader = summaryLoader; + mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + IntentFilter filter = new IntentFilter(); + filter.addAction(AudioManager.VOLUME_CHANGED_ACTION); + filter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION); + filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION); + filter.addAction(AudioManager.STREAM_MUTE_CHANGED_ACTION); + filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED); + mContext.registerReceiver(this, filter); + } else { + mContext.unregisterReceiver(this); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + String percent = NumberFormat.getPercentInstance().format( + (double) mAudioManager.getStreamVolume(AudioManager.STREAM_RING) / maxVolume); + mSummaryLoader.setSummary(this, + mContext.getString(R.string.sound_settings_summary, percent)); + } + } + + public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY + = new SummaryLoader.SummaryProviderFactory() { + @Override + public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity, + SummaryLoader summaryLoader) { + return new SummaryProvider(activity, summaryLoader); + } + }; + // === Indexing === public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = @@ -685,7 +545,7 @@ public class NotificationSettings extends SettingsPreferenceFragment implements public List getXmlResourcesToIndex( Context context, boolean enabled) { final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = R.xml.notification_settings; + sir.xmlResId = R.xml.configure_notification_settings; return Arrays.asList(sir); } diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java index 39ec08cf5f6..37433968766 100644 --- a/src/com/android/settings/notification/ZenModeSettings.java +++ b/src/com/android/settings/notification/ZenModeSettings.java @@ -18,26 +18,19 @@ package com.android.settings.notification; import android.app.NotificationManager; import android.app.NotificationManager.Policy; -import android.content.Context; -import android.content.res.Resources; import android.os.Bundle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; -import android.util.SparseArray; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import com.android.internal.logging.MetricsLogger; import com.android.settings.R; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settings.search.SearchIndexableRaw; +import com.android.settings.SettingsActivity; -import java.util.ArrayList; -import java.util.List; - -public class ZenModeSettings extends ZenModeSettingsBase implements Indexable { +public class ZenModeSettings extends ZenModeSettingsBase { private static final String KEY_PRIORITY_SETTINGS = "priority_settings"; - private static final String KEY_AUTOMATION_SETTINGS = "automation_settings"; - private static final String KEY_VISUAL_INTERRUPTIONS_SETTINGS = "visual_interruptions_settings"; private Preference mPrioritySettings; @@ -49,9 +42,6 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable { final PreferenceScreen root = getPreferenceScreen(); mPrioritySettings = root.findPreference(KEY_PRIORITY_SETTINGS); - if (!isScheduleSupported(mContext)) { - removePreference(KEY_AUTOMATION_SETTINGS); - } } @Override @@ -79,6 +69,23 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable { updatePrioritySettingsSummary(); } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.zen_settings_menu, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.zen_access: + ((SettingsActivity) getActivity()).startPreferencePanel( + ZenAccessSettings.class.getCanonicalName(), null, + R.string.manage_zen_access_title, null, this, 0); + return true; + } + return super.onOptionsItemSelected(item); + } + private void updatePrioritySettingsSummary() { Policy policy = NotificationManager.from(mContext).getNotificationPolicy(); String s = getResources().getString(R.string.zen_mode_alarms); @@ -117,47 +124,8 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable { return s; } - private static SparseArray allKeyTitles() { - final SparseArray rt = new SparseArray(); - rt.put(R.string.zen_mode_priority_settings_title, KEY_PRIORITY_SETTINGS); - rt.put(R.string.zen_mode_automation_settings_title, KEY_AUTOMATION_SETTINGS); - rt.put(R.string.zen_mode_visual_interruptions_settings_title, - KEY_VISUAL_INTERRUPTIONS_SETTINGS); - return rt; - } - @Override protected int getHelpResource() { return R.string.help_uri_interruptions; } - - // Enable indexing of searchable data - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - - @Override - public List getRawDataToIndex(Context context, boolean enabled) { - final SparseArray keyTitles = allKeyTitles(); - final int N = keyTitles.size(); - final List result = new ArrayList(N); - final Resources res = context.getResources(); - for (int i = 0; i < N; i++) { - final SearchIndexableRaw data = new SearchIndexableRaw(context); - data.key = keyTitles.valueAt(i); - data.title = res.getString(keyTitles.keyAt(i)); - data.screenTitle = res.getString(R.string.zen_mode_settings_title); - result.add(data); - } - return result; - } - - @Override - public List getNonIndexableKeys(Context context) { - final ArrayList rt = new ArrayList(); - if (!isScheduleSupported(context)) { - rt.add(KEY_AUTOMATION_SETTINGS); - } - return rt; - } - }; } diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java index 1a34062fbf4..4c8663f910c 100644 --- a/src/com/android/settings/notification/ZenModeSettingsBase.java +++ b/src/com/android/settings/notification/ZenModeSettingsBase.java @@ -122,11 +122,6 @@ abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment { NotificationManager.from(mContext).setZenMode(zenMode, conditionId, TAG); } - protected static boolean isScheduleSupported(Context context) { - return NotificationManager.from(context) - .isSystemConditionProviderEnabled(ZenModeConfig.SCHEDULE_PATH); - } - private List getZenModeRules() { return NotificationManager.from(mContext).getAutomaticZenRules(); } diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java index 1f464df4a3c..4ac4fb85686 100644 --- a/src/com/android/settings/search/Ranking.java +++ b/src/com/android/settings/search/Ranking.java @@ -42,8 +42,9 @@ import com.android.settings.inputmethod.InputMethodAndLanguageSettings; import com.android.settings.location.LocationSettings; import com.android.settings.location.ScanningSettings; import com.android.settings.net.DataUsageMeteredSettings; -import com.android.settings.notification.NotificationSettings; +import com.android.settings.notification.ConfigureNotificationSettings; import com.android.settings.notification.OtherSoundSettings; +import com.android.settings.notification.SoundSettings; import com.android.settings.notification.ZenModeAutomationSettings; import com.android.settings.notification.ZenModePrioritySettings; import com.android.settings.notification.ZenModeSettings; @@ -71,20 +72,21 @@ public final class Ranking { public static final int RANK_DISPLAY = 7; public static final int RANK_WALLPAPER = 8; public static final int RANK_NOTIFICATIONS = 9; - public static final int RANK_APPS = 10; - public static final int RANK_STORAGE = 11; - public static final int RANK_POWER_USAGE = 12; - public static final int RANK_USERS = 13; - public static final int RANK_LOCATION = 14; - public static final int RANK_SECURITY = 15; - public static final int RANK_ACCOUNT = 16; - public static final int RANK_IME = 17; - public static final int RANK_PRIVACY = 18; - public static final int RANK_DATE_TIME = 19; - public static final int RANK_ACCESSIBILITY = 20; - public static final int RANK_PRINTING = 21; - public static final int RANK_DEVELOPEMENT = 22; - public static final int RANK_DEVICE_INFO = 23; + public static final int RANK_SOUND = 10; + public static final int RANK_APPS = 11; + public static final int RANK_STORAGE = 12; + public static final int RANK_POWER_USAGE = 13; + public static final int RANK_USERS = 14; + public static final int RANK_LOCATION = 15; + public static final int RANK_SECURITY = 16; + public static final int RANK_ACCOUNT = 17; + public static final int RANK_IME = 18; + public static final int RANK_PRIVACY = 19; + public static final int RANK_DATE_TIME = 20; + public static final int RANK_ACCESSIBILITY = 21; + public static final int RANK_PRINTING = 22; + public static final int RANK_DEVELOPEMENT = 23; + public static final int RANK_DEVICE_INFO = 24; public static final int RANK_UNDEFINED = -1; public static final int RANK_OTHERS = 1024; @@ -124,8 +126,11 @@ public final class Ranking { // Wallpapers sRankMap.put(WallpaperTypeSettings.class.getName(), RANK_WALLPAPER); + // Sound + sRankMap.put(SoundSettings.class.getName(), RANK_SOUND); + // Notifications - sRankMap.put(NotificationSettings.class.getName(), RANK_NOTIFICATIONS); + sRankMap.put(ConfigureNotificationSettings.class.getName(), RANK_NOTIFICATIONS); sRankMap.put(OtherSoundSettings.class.getName(), RANK_NOTIFICATIONS); sRankMap.put(ZenModeSettings.class.getName(), RANK_NOTIFICATIONS); sRankMap.put(ZenModePrioritySettings.class.getName(), RANK_NOTIFICATIONS); diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 7e669e0a8a0..376b2ebfb39 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -44,8 +44,9 @@ import com.android.settings.inputmethod.InputMethodAndLanguageSettings; import com.android.settings.location.LocationSettings; import com.android.settings.location.ScanningSettings; import com.android.settings.net.DataUsageMeteredSettings; -import com.android.settings.notification.NotificationSettings; +import com.android.settings.notification.ConfigureNotificationSettings; import com.android.settings.notification.OtherSoundSettings; +import com.android.settings.notification.SoundSettings; import com.android.settings.notification.ZenModePrioritySettings; import com.android.settings.notification.ZenModeSettings; import com.android.settings.notification.ZenModeVisualInterruptionSettings; @@ -144,24 +145,31 @@ public final class SearchIndexableResources { WallpaperTypeSettings.class.getName(), R.drawable.ic_settings_display)); - sResMap.put(NotificationSettings.class.getName(), + sResMap.put(ConfigureNotificationSettings.class.getName(), new SearchIndexableResource( - Ranking.getRankForClassName(NotificationSettings.class.getName()), - NO_DATA_RES_ID, - NotificationSettings.class.getName(), + Ranking.getRankForClassName(ConfigureNotificationSettings.class.getName()), + R.xml.configure_notification_settings, + ConfigureNotificationSettings.class.getName(), R.drawable.ic_settings_notifications)); + sResMap.put(SoundSettings.class.getName(), + new SearchIndexableResource( + Ranking.getRankForClassName(SoundSettings.class.getName()), + R.xml.sound_settings, + SoundSettings.class.getName(), + R.drawable.ic_settings_sound)); + sResMap.put(OtherSoundSettings.class.getName(), new SearchIndexableResource( Ranking.getRankForClassName(OtherSoundSettings.class.getName()), NO_DATA_RES_ID, OtherSoundSettings.class.getName(), - R.drawable.ic_settings_notifications)); + R.drawable.ic_settings_sound)); sResMap.put(ZenModeSettings.class.getName(), new SearchIndexableResource( Ranking.getRankForClassName(ZenModeSettings.class.getName()), - NO_DATA_RES_ID, + R.xml.zen_mode_settings, ZenModeSettings.class.getName(), R.drawable.ic_settings_notifications));