1 /* 2 * Copyright (C) 2016 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.content.ContentResolver; 20 import android.content.Context; 21 import android.database.ContentObserver; 22 import android.net.Uri; 23 import android.os.Handler; 24 import android.os.UserHandle; 25 import android.os.UserManager; 26 import android.provider.Settings; 27 import android.support.v7.preference.Preference; 28 import android.support.v7.preference.PreferenceScreen; 29 import android.text.TextUtils; 30 import android.util.Log; 31 32 import com.android.internal.widget.LockPatternUtils; 33 import com.android.settings.R; 34 import com.android.settings.Utils; 35 import com.android.settings.core.PreferenceController; 36 import com.android.settings.core.lifecycle.LifecycleObserver; 37 import com.android.settings.core.lifecycle.events.OnPause; 38 import com.android.settings.core.lifecycle.events.OnResume; 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 46 public class LockScreenNotificationPreferenceController extends PreferenceController implements 47 Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { 48 49 private static final String TAG = "LockScreenNotifPref"; 50 51 private final String mSettingKey; 52 private final String mWorkSettingCategoryKey; 53 private final String mWorkSettingKey; 54 55 private RestrictedDropDownPreference mLockscreen; 56 private RestrictedDropDownPreference mLockscreenProfile; 57 58 private final int mProfileChallengeUserId; 59 private final boolean mSecure; 60 private final boolean mSecureProfile; 61 62 private SettingObserver mSettingObserver; 63 private int mLockscreenSelectedValue; 64 private int mLockscreenSelectedValueProfile; 65 66 public LockScreenNotificationPreferenceController(Context context) { 67 this(context, null, null, null); 68 } 69 70 public LockScreenNotificationPreferenceController(Context context, 71 String settingKey, String workSettingCategoryKey, String workSettingKey) { 72 super(context); 73 mSettingKey = settingKey; 74 mWorkSettingCategoryKey = workSettingCategoryKey; 75 mWorkSettingKey = workSettingKey; 76 77 mProfileChallengeUserId = Utils.getManagedProfileId( 78 UserManager.get(context), UserHandle.myUserId()); 79 final LockPatternUtils utils = new LockPatternUtils(context); 80 final boolean isUnified = 81 !utils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId); 82 mSecure = utils.isSecure(UserHandle.myUserId()); 83 mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL) 84 && (utils.isSecure(mProfileChallengeUserId) || (isUnified && mSecure)); 85 } 86 87 @Override 88 public void displayPreference(PreferenceScreen screen) { 89 super.displayPreference(screen); 90 mLockscreen = 91 (RestrictedDropDownPreference) screen.findPreference(mSettingKey); 92 if (mLockscreen == null) { 93 Log.i(TAG, "Preference not found: " + mSettingKey); 94 return; 95 } 96 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 97 mLockscreenProfile = (RestrictedDropDownPreference) screen.findPreference( 98 mWorkSettingKey); 99 } else { 100 removePreference(screen, mWorkSettingKey); 101 removePreference(screen, mWorkSettingCategoryKey); 102 } 103 mSettingObserver = new SettingObserver(); 104 initLockScreenNotificationPrefDisplay(); 105 initLockscreenNotificationPrefForProfile(); 106 } 107 108 private void initLockScreenNotificationPrefDisplay() { 109 ArrayList<CharSequence> entries = new ArrayList<>(); 110 ArrayList<CharSequence> values = new ArrayList<>(); 111 entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable)); 112 values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable)); 113 114 String summaryShowEntry = 115 mContext.getString(R.string.lock_screen_notifications_summary_show); 116 String summaryShowEntryValue = 117 Integer.toString(R.string.lock_screen_notifications_summary_show); 118 entries.add(summaryShowEntry); 119 values.add(summaryShowEntryValue); 120 setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue, 121 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 122 123 if (mSecure) { 124 String summaryHideEntry = 125 mContext.getString(R.string.lock_screen_notifications_summary_hide); 126 String summaryHideEntryValue = 127 Integer.toString(R.string.lock_screen_notifications_summary_hide); 128 entries.add(summaryHideEntry); 129 values.add(summaryHideEntryValue); 130 setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue, 131 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 132 } 133 134 mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()])); 135 mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()])); 136 updateLockscreenNotifications(); 137 138 if (mLockscreen.getEntries().length > 1) { 139 mLockscreen.setOnPreferenceChangeListener(this); 140 } else { 141 // There is one or less option for the user, disable the drop down. 142 mLockscreen.setEnabled(false); 143 } 144 } 145 146 private void initLockscreenNotificationPrefForProfile() { 147 if (mLockscreenProfile == null) { 148 Log.i(TAG, "Preference not found: " + mWorkSettingKey); 149 return; 150 } 151 ArrayList<CharSequence> entries = new ArrayList<>(); 152 ArrayList<CharSequence> values = new ArrayList<>(); 153 entries.add(mContext.getString(R.string.lock_screen_notifications_summary_disable_profile)); 154 values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile)); 155 156 String summaryShowEntry = mContext.getString( 157 R.string.lock_screen_notifications_summary_show_profile); 158 String summaryShowEntryValue = Integer.toString( 159 R.string.lock_screen_notifications_summary_show_profile); 160 entries.add(summaryShowEntry); 161 values.add(summaryShowEntryValue); 162 setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue, 163 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 164 165 if (mSecureProfile) { 166 String summaryHideEntry = mContext.getString( 167 R.string.lock_screen_notifications_summary_hide_profile); 168 String summaryHideEntryValue = Integer.toString( 169 R.string.lock_screen_notifications_summary_hide_profile); 170 entries.add(summaryHideEntry); 171 values.add(summaryHideEntryValue); 172 setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue, 173 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 174 } 175 mLockscreenProfile.setOnPreClickListener( 176 (Preference p) -> Utils.startQuietModeDialogIfNecessary(mContext, 177 UserManager.get(mContext), mProfileChallengeUserId) 178 ); 179 180 mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()])); 181 mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()])); 182 updateLockscreenNotificationsForProfile(); 183 if (mLockscreenProfile.getEntries().length > 1) { 184 mLockscreenProfile.setOnPreferenceChangeListener(this); 185 } else { 186 // There is one or less option for the user, disable the drop down. 187 mLockscreenProfile.setEnabled(false); 188 } 189 } 190 191 @Override 192 public String getPreferenceKey() { 193 return null; 194 } 195 196 @Override 197 public boolean isAvailable() { 198 return false; 199 } 200 201 @Override 202 public void onResume() { 203 if (mSettingObserver != null) { 204 mSettingObserver.register(mContext.getContentResolver(), true /* register */); 205 } 206 } 207 208 @Override 209 public void onPause() { 210 if (mSettingObserver != null) { 211 mSettingObserver.register(mContext.getContentResolver(), false /* register */); 212 } 213 } 214 215 @Override 216 public boolean onPreferenceChange(Preference preference, Object newValue) { 217 final String key = preference.getKey(); 218 if (TextUtils.equals(mWorkSettingKey, key)) { 219 final int val = Integer.parseInt((String) newValue); 220 if (val == mLockscreenSelectedValueProfile) { 221 return false; 222 } 223 final boolean enabled = 224 val != R.string.lock_screen_notifications_summary_disable_profile; 225 final boolean show = 226 val == R.string.lock_screen_notifications_summary_show_profile; 227 Settings.Secure.putIntForUser(mContext.getContentResolver(), 228 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 229 show ? 1 : 0, mProfileChallengeUserId); 230 Settings.Secure.putIntForUser(mContext.getContentResolver(), 231 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 232 enabled ? 1 : 0, mProfileChallengeUserId); 233 mLockscreenSelectedValueProfile = val; 234 return true; 235 } else if (TextUtils.equals(mSettingKey, key)) { 236 final int val = Integer.parseInt((String) newValue); 237 if (val == mLockscreenSelectedValue) { 238 return false; 239 } 240 final boolean enabled = 241 val != R.string.lock_screen_notifications_summary_disable; 242 final boolean show = val == R.string.lock_screen_notifications_summary_show; 243 Settings.Secure.putInt(mContext.getContentResolver(), 244 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0); 245 Settings.Secure.putInt(mContext.getContentResolver(), 246 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0); 247 mLockscreenSelectedValue = val; 248 return true; 249 } 250 return false; 251 } 252 253 private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry, 254 CharSequence entryValue, int keyguardNotificationFeatures) { 255 RestrictedLockUtils.EnforcedAdmin admin = 256 RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 257 mContext, keyguardNotificationFeatures, UserHandle.myUserId()); 258 if (admin != null && mLockscreen != null) { 259 RestrictedDropDownPreference.RestrictedItem item = 260 new RestrictedDropDownPreference.RestrictedItem(entry, entryValue, admin); 261 mLockscreen.addRestrictedItem(item); 262 } 263 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 264 RestrictedLockUtils.EnforcedAdmin profileAdmin = 265 RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 266 mContext, keyguardNotificationFeatures, mProfileChallengeUserId); 267 if (profileAdmin != null && mLockscreenProfile != null) { 268 RestrictedDropDownPreference.RestrictedItem item = 269 new RestrictedDropDownPreference.RestrictedItem( 270 entry, entryValue, profileAdmin); 271 mLockscreenProfile.addRestrictedItem(item); 272 } 273 } 274 } 275 276 public int getSummaryResource() { 277 final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId()); 278 final boolean allowPrivate = !mSecure 279 || getLockscreenAllowPrivateNotifications(UserHandle.myUserId()); 280 return !enabled ? R.string.lock_screen_notifications_summary_disable : 281 allowPrivate ? R.string.lock_screen_notifications_summary_show : 282 R.string.lock_screen_notifications_summary_hide; 283 } 284 285 private void updateLockscreenNotifications() { 286 if (mLockscreen == null) { 287 return; 288 } 289 mLockscreenSelectedValue = getSummaryResource(); 290 mLockscreen.setSummary("%s"); 291 mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue)); 292 } 293 294 private void updateLockscreenNotificationsForProfile() { 295 if (mProfileChallengeUserId == UserHandle.USER_NULL) { 296 return; 297 } 298 if (mLockscreenProfile == null) { 299 return; 300 } 301 final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId); 302 final boolean allowPrivate = !mSecureProfile 303 || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId); 304 mLockscreenProfile.setSummary("%s"); 305 mLockscreenSelectedValueProfile = !enabled 306 ? R.string.lock_screen_notifications_summary_disable_profile 307 : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile 308 : R.string.lock_screen_notifications_summary_hide_profile); 309 mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile)); 310 } 311 312 private boolean getLockscreenNotificationsEnabled(int userId) { 313 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 314 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0; 315 } 316 317 private boolean getLockscreenAllowPrivateNotifications(int userId) { 318 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 319 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0; 320 } 321 322 class SettingObserver extends ContentObserver { 323 324 private final Uri LOCK_SCREEN_PRIVATE_URI = 325 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); 326 private final Uri LOCK_SCREEN_SHOW_URI = 327 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS); 328 329 public SettingObserver() { 330 super(new Handler()); 331 } 332 333 public void register(ContentResolver cr, boolean register) { 334 if (register) { 335 cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this); 336 cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this); 337 } else { 338 cr.unregisterContentObserver(this); 339 } 340 } 341 342 @Override 343 public void onChange(boolean selfChange, Uri uri) { 344 super.onChange(selfChange, uri); 345 if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) { 346 updateLockscreenNotifications(); 347 if (mProfileChallengeUserId != UserHandle.USER_NULL) { 348 updateLockscreenNotificationsForProfile(); 349 } 350 } 351 } 352 } 353 } 354