1 /** 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.notification; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.database.ContentObserver; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.provider.Settings; 29 import android.support.v7.preference.Preference; 30 import android.support.v7.preference.Preference.OnPreferenceChangeListener; 31 import android.support.v7.preference.TwoStatePreference; 32 import android.util.Log; 33 import com.android.internal.logging.MetricsProto.MetricsEvent; 34 import com.android.internal.widget.LockPatternUtils; 35 import com.android.settings.R; 36 import com.android.settings.RestrictedListPreference.RestrictedItem; 37 import com.android.settings.SettingsPreferenceFragment; 38 import com.android.settings.Utils; 39 import com.android.settingslib.RestrictedLockUtils; 40 41 import java.util.ArrayList; 42 43 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; 44 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; 45 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 46 47 public class ConfigureNotificationSettings extends SettingsPreferenceFragment { 48 private static final String TAG = "ConfigNotiSettings"; 49 50 private static final String KEY_NOTIFICATION_PULSE = "notification_pulse"; 51 private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications"; 52 private static final String KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS = 53 "lock_screen_notifications_profile"; 54 55 private final SettingsObserver mSettingsObserver = new SettingsObserver(); 56 57 private Context mContext; 58 59 private TwoStatePreference mNotificationPulse; 60 private RestrictedDropDownPreference mLockscreen; 61 private RestrictedDropDownPreference mLockscreenProfile; 62 private boolean mSecure; 63 private boolean mSecureProfile; 64 private int mLockscreenSelectedValue; 65 private int mLockscreenSelectedValueProfile; 66 private int mProfileChallengeUserId; 67 68 @Override 69 protected int getMetricsCategory() { 70 return MetricsEvent.CONFIGURE_NOTIFICATION; 71 } 72 73 @Override 74 public void onCreate(Bundle savedInstanceState) { 75 super.onCreate(savedInstanceState); 76 mContext = getActivity(); 77 mProfileChallengeUserId = Utils.getManagedProfileId( 78 UserManager.get(mContext), UserHandle.myUserId()); 79 80 final LockPatternUtils utils = new LockPatternUtils(getActivity()); 81 final boolean isUnified = 82 !utils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId); 83 84 mSecure = utils.isSecure(UserHandle.myUserId()); 85 mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL) 86 && (utils.isSecure(mProfileChallengeUserId) || (isUnified && mSecure)); 87 88 addPreferencesFromResource(R.xml.configure_notification_settings); 89 90 initPulse(); 91 initLockscreenNotifications(); 92 93 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 94 addPreferencesFromResource(R.xml.configure_notification_settings_profile); 95 initLockscreenNotificationsForProfile(); 96 } 97 98 } 99 100 @Override 101 public void onResume() { 102 super.onResume(); 103 mSettingsObserver.register(true); 104 } 105 106 @Override 107 public void onPause() { 108 super.onPause(); 109 mSettingsObserver.register(false); 110 } 111 112 // === Pulse notification light === 113 114 private void initPulse() { 115 mNotificationPulse = 116 (TwoStatePreference) getPreferenceScreen().findPreference(KEY_NOTIFICATION_PULSE); 117 if (mNotificationPulse == null) { 118 Log.i(TAG, "Preference not found: " + KEY_NOTIFICATION_PULSE); 119 return; 120 } 121 if (!getResources() 122 .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) { 123 getPreferenceScreen().removePreference(mNotificationPulse); 124 } else { 125 updatePulse(); 126 mNotificationPulse.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 127 @Override 128 public boolean onPreferenceChange(Preference preference, Object newValue) { 129 final boolean val = (Boolean)newValue; 130 return Settings.System.putInt(getContentResolver(), 131 Settings.System.NOTIFICATION_LIGHT_PULSE, 132 val ? 1 : 0); 133 } 134 }); 135 } 136 } 137 138 private void updatePulse() { 139 if (mNotificationPulse == null) { 140 return; 141 } 142 try { 143 mNotificationPulse.setChecked(Settings.System.getInt(getContentResolver(), 144 Settings.System.NOTIFICATION_LIGHT_PULSE) == 1); 145 } catch (Settings.SettingNotFoundException snfe) { 146 Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found"); 147 } 148 } 149 150 private void initLockscreenNotifications() { 151 mLockscreen = (RestrictedDropDownPreference) getPreferenceScreen().findPreference( 152 KEY_LOCK_SCREEN_NOTIFICATIONS); 153 if (mLockscreen == null) { 154 Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS); 155 return; 156 } 157 158 ArrayList<CharSequence> entries = new ArrayList<>(); 159 ArrayList<CharSequence> values = new ArrayList<>(); 160 entries.add(getString(R.string.lock_screen_notifications_summary_disable)); 161 values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable)); 162 163 String summaryShowEntry = getString(R.string.lock_screen_notifications_summary_show); 164 String summaryShowEntryValue = Integer.toString( 165 R.string.lock_screen_notifications_summary_show); 166 entries.add(summaryShowEntry); 167 values.add(summaryShowEntryValue); 168 setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue, 169 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 170 171 if (mSecure) { 172 String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide); 173 String summaryHideEntryValue = Integer.toString( 174 R.string.lock_screen_notifications_summary_hide); 175 entries.add(summaryHideEntry); 176 values.add(summaryHideEntryValue); 177 setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue, 178 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 179 } 180 181 mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()])); 182 mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()])); 183 updateLockscreenNotifications(); 184 if (mLockscreen.getEntries().length > 1) { 185 mLockscreen.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 186 @Override 187 public boolean onPreferenceChange(Preference preference, Object newValue) { 188 final int val = Integer.parseInt((String) newValue); 189 if (val == mLockscreenSelectedValue) { 190 return false; 191 } 192 final boolean enabled = 193 val != R.string.lock_screen_notifications_summary_disable; 194 final boolean show = val == R.string.lock_screen_notifications_summary_show; 195 Settings.Secure.putInt(getContentResolver(), 196 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0); 197 Settings.Secure.putInt(getContentResolver(), 198 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0); 199 mLockscreenSelectedValue = val; 200 return true; 201 } 202 }); 203 } else { 204 // There is one or less option for the user, disable the drop down. 205 mLockscreen.setEnabled(false); 206 } 207 } 208 209 // === Lockscreen (public / private) notifications === 210 private void initLockscreenNotificationsForProfile() { 211 mLockscreenProfile = (RestrictedDropDownPreference) getPreferenceScreen() 212 .findPreference(KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS); 213 if (mLockscreenProfile == null) { 214 Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS); 215 return; 216 } 217 ArrayList<CharSequence> entries = new ArrayList<>(); 218 ArrayList<CharSequence> values = new ArrayList<>(); 219 entries.add(getString(R.string.lock_screen_notifications_summary_disable_profile)); 220 values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile)); 221 222 String summaryShowEntry = getString( 223 R.string.lock_screen_notifications_summary_show_profile); 224 String summaryShowEntryValue = Integer.toString( 225 R.string.lock_screen_notifications_summary_show_profile); 226 entries.add(summaryShowEntry); 227 values.add(summaryShowEntryValue); 228 setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue, 229 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 230 231 if (mSecureProfile) { 232 String summaryHideEntry = getString( 233 R.string.lock_screen_notifications_summary_hide_profile); 234 String summaryHideEntryValue = Integer.toString( 235 R.string.lock_screen_notifications_summary_hide_profile); 236 entries.add(summaryHideEntry); 237 values.add(summaryHideEntryValue); 238 setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue, 239 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 240 } 241 242 mLockscreenProfile.setOnPreClickListener( 243 (Preference p) -> Utils.startQuietModeDialogIfNecessary(mContext, 244 UserManager.get(mContext), 245 mProfileChallengeUserId) 246 ); 247 248 mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()])); 249 mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()])); 250 updateLockscreenNotificationsForProfile(); 251 if (mLockscreenProfile.getEntries().length > 1) { 252 mLockscreenProfile.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 253 @Override 254 public boolean onPreferenceChange(Preference preference, Object newValue) { 255 final int val = Integer.parseInt((String) newValue); 256 if (val == mLockscreenSelectedValueProfile) { 257 return false; 258 } 259 final boolean enabled = 260 val != R.string.lock_screen_notifications_summary_disable_profile; 261 final boolean show = 262 val == R.string.lock_screen_notifications_summary_show_profile; 263 Settings.Secure.putIntForUser(getContentResolver(), 264 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 265 show ? 1 : 0, mProfileChallengeUserId); 266 Settings.Secure.putIntForUser(getContentResolver(), 267 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 268 enabled ? 1 : 0, mProfileChallengeUserId); 269 mLockscreenSelectedValueProfile = val; 270 return true; 271 } 272 }); 273 } else { 274 // There is one or less option for the user, disable the drop down. 275 mLockscreenProfile.setEnabled(false); 276 } 277 } 278 279 private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry, 280 CharSequence entryValue, int keyguardNotificationFeatures) { 281 EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 282 mContext, keyguardNotificationFeatures, UserHandle.myUserId()); 283 if (admin != null && mLockscreen != null) { 284 RestrictedDropDownPreference.RestrictedItem item = 285 new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin); 286 mLockscreen.addRestrictedItem(item); 287 } 288 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 289 EnforcedAdmin profileAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 290 mContext, keyguardNotificationFeatures, mProfileChallengeUserId); 291 if (profileAdmin != null && mLockscreenProfile != null) { 292 RestrictedDropDownPreference.RestrictedItem item = 293 new RestrictedDropDownPreference.RestrictedItem( 294 entry, entryValue, profileAdmin); 295 mLockscreenProfile.addRestrictedItem(item); 296 } 297 } 298 } 299 300 private void updateLockscreenNotifications() { 301 if (mLockscreen == null) { 302 return; 303 } 304 final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId()); 305 final boolean allowPrivate = !mSecure 306 || getLockscreenAllowPrivateNotifications(UserHandle.myUserId()); 307 mLockscreenSelectedValue = !enabled ? R.string.lock_screen_notifications_summary_disable : 308 allowPrivate ? R.string.lock_screen_notifications_summary_show : 309 R.string.lock_screen_notifications_summary_hide; 310 mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue)); 311 } 312 313 private void updateLockscreenNotificationsForProfile() { 314 if (mProfileChallengeUserId == UserHandle.USER_NULL) { 315 return; 316 } 317 if (mLockscreenProfile == null) { 318 return; 319 } 320 final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId); 321 final boolean allowPrivate = !mSecureProfile 322 || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId); 323 mLockscreenSelectedValueProfile = !enabled 324 ? R.string.lock_screen_notifications_summary_disable_profile 325 : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile 326 : R.string.lock_screen_notifications_summary_hide_profile); 327 mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile)); 328 } 329 330 private boolean getLockscreenNotificationsEnabled(int userId) { 331 return Settings.Secure.getIntForUser(getContentResolver(), 332 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0; 333 } 334 335 private boolean getLockscreenAllowPrivateNotifications(int userId) { 336 return Settings.Secure.getIntForUser(getContentResolver(), 337 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0; 338 } 339 340 341 // === Callbacks === 342 343 private final class SettingsObserver extends ContentObserver { 344 private final Uri NOTIFICATION_LIGHT_PULSE_URI = 345 Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE); 346 private final Uri LOCK_SCREEN_PRIVATE_URI = 347 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); 348 private final Uri LOCK_SCREEN_SHOW_URI = 349 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 350 351 public SettingsObserver() { 352 super(new Handler()); 353 } 354 355 public void register(boolean register) { 356 final ContentResolver cr = getContentResolver(); 357 if (register) { 358 cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this); 359 cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this); 360 cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this); 361 } else { 362 cr.unregisterContentObserver(this); 363 } 364 } 365 366 @Override 367 public void onChange(boolean selfChange, Uri uri) { 368 super.onChange(selfChange, uri); 369 if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { 370 updatePulse(); 371 } 372 if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) { 373 updateLockscreenNotifications(); 374 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 375 updateLockscreenNotificationsForProfile(); 376 } 377 } 378 } 379 } 380 } 381