diff --git a/res/values/strings.xml b/res/values/strings.xml index 208737cdd93..14b78999fd7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6159,7 +6159,7 @@ - Configure notifications + Notification preferences Advanced diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index 8778abb97de..2bdb790a75f 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" /> + + + + + + diff --git a/res/xml/configure_notification_settings_profile.xml b/res/xml/configure_notification_settings_profile.xml deleted file mode 100644 index 301f3c0eda2..00000000000 --- a/res/xml/configure_notification_settings_profile.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java index 3f53ec923ab..0ed49d5520d 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 @@ public class ConfigureNotificationSettings extends SettingsPreferenceFragment { } @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 entries = new ArrayList<>(); - ArrayList 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 entries = new ArrayList<>(); - ArrayList 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 getPreferenceControllers(Context context) { + final List 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 00000000000..f349a8493e6 --- /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 entries = new ArrayList<>(); + ArrayList 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 entries = new ArrayList<>(); + ArrayList 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 00000000000..03832e5d234 --- /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 8fc290e9eb5..6d11041af06 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 @@ public class DashboardFragmentTest { 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 00000000000..4eb33e989e5 --- /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); + } +}