1 /* 2 * Copyright (C) 2019 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 static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; 20 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; 21 import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; 22 23 import android.app.KeyguardManager; 24 import android.content.Context; 25 import android.content.pm.UserInfo; 26 import android.database.ContentObserver; 27 import android.os.Handler; 28 import android.os.Looper; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.provider.Settings; 32 33 import androidx.preference.PreferenceScreen; 34 35 import com.android.internal.widget.LockPatternUtils; 36 import com.android.settings.R; 37 import com.android.settings.core.TogglePreferenceController; 38 import com.android.settings.overlay.FeatureFactory; 39 import com.android.settingslib.RestrictedLockUtils; 40 import com.android.settingslib.RestrictedLockUtilsInternal; 41 import com.android.settingslib.RestrictedSwitchPreference; 42 import com.android.settingslib.core.lifecycle.LifecycleObserver; 43 import com.android.settingslib.core.lifecycle.events.OnStart; 44 import com.android.settingslib.core.lifecycle.events.OnStop; 45 46 import java.util.List; 47 48 /** 49 * The controller of the sensitive notifications. 50 */ 51 public class RedactNotificationPreferenceController extends TogglePreferenceController implements 52 LifecycleObserver, OnStart, OnStop { 53 private static final String TAG = "LockScreenNotifPref"; 54 55 static final String KEY_LOCKSCREEN_REDACT = "lock_screen_redact"; 56 static final String KEY_LOCKSCREEN_WORK_PROFILE_REDACT = "lock_screen_work_redact"; 57 58 private UserManager mUm; 59 private KeyguardManager mKm; 60 int mProfileUserId; 61 private RestrictedSwitchPreference mPreference; 62 private ContentObserver mContentObserver = 63 new ContentObserver(new Handler(Looper.getMainLooper())) { 64 @Override 65 public void onChange(boolean selfChange) { 66 if (mPreference != null) { 67 mPreference.setEnabled( 68 getAvailabilityStatus() != DISABLED_DEPENDENT_SETTING); 69 } 70 } 71 }; 72 RedactNotificationPreferenceController(Context context, String settingKey)73 public RedactNotificationPreferenceController(Context context, String settingKey) { 74 super(context, settingKey); 75 76 mUm = context.getSystemService(UserManager.class); 77 mKm = context.getSystemService(KeyguardManager.class); 78 79 mProfileUserId = UserHandle.myUserId(); 80 final List<UserInfo> profiles = mUm.getProfiles(UserHandle.myUserId()); 81 final int count = profiles.size(); 82 for (int i = 0; i < count; i++) { 83 final UserInfo profile = profiles.get(i); 84 if (profile.isManagedProfile() 85 && profile.getUserHandle().getIdentifier() != UserHandle.myUserId()) { 86 mProfileUserId = profile.getUserHandle().getIdentifier(); 87 } 88 } 89 } 90 91 @Override displayPreference(PreferenceScreen screen)92 public void displayPreference(PreferenceScreen screen) { 93 super.displayPreference(screen); 94 mPreference = screen.findPreference(getPreferenceKey()); 95 96 int userId = KEY_LOCKSCREEN_REDACT.equals(getPreferenceKey()) 97 ? UserHandle.myUserId() : mProfileUserId; 98 if (userId != UserHandle.USER_NULL) { 99 mPreference.setDisabledByAdmin(getEnforcedAdmin(userId)); 100 } 101 } 102 103 @Override isChecked()104 public boolean isChecked() { 105 int userId = KEY_LOCKSCREEN_REDACT.equals(getPreferenceKey()) 106 ? UserHandle.myUserId() : mProfileUserId; 107 108 return getAllowPrivateNotifications(userId); 109 } 110 111 @Override setChecked(boolean isChecked)112 public boolean setChecked(boolean isChecked) { 113 int userId = KEY_LOCKSCREEN_REDACT.equals(getPreferenceKey()) 114 ? UserHandle.myUserId() : mProfileUserId; 115 116 Settings.Secure.putIntForUser(mContext.getContentResolver(), 117 Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, isChecked ? 1 : 0, userId); 118 return true; 119 } 120 121 @Override getAvailabilityStatus()122 public int getAvailabilityStatus() { 123 // hide work profile setting if no work profile 124 if (KEY_LOCKSCREEN_WORK_PROFILE_REDACT.equals(getPreferenceKey()) 125 && mProfileUserId == UserHandle.myUserId()) { 126 return CONDITIONALLY_UNAVAILABLE; 127 } 128 129 int userId = KEY_LOCKSCREEN_REDACT.equals(getPreferenceKey()) 130 ? UserHandle.myUserId() : mProfileUserId; 131 132 // hide if lockscreen isn't secure for this user 133 final LockPatternUtils utils = FeatureFactory.getFeatureFactory() 134 .getSecurityFeatureProvider() 135 .getLockPatternUtils(mContext); 136 if (!utils.isSecure(userId)) { 137 return CONDITIONALLY_UNAVAILABLE; 138 } 139 140 // all notifs hidden? disabled 141 if (!getLockscreenNotificationsEnabled(userId)) { 142 return DISABLED_DEPENDENT_SETTING; 143 } 144 145 // specifically the work profile setting requires the work profile to be unlocked 146 if (KEY_LOCKSCREEN_WORK_PROFILE_REDACT.equals(getPreferenceKey())) { 147 if (mKm.isDeviceLocked(mProfileUserId)) { 148 return DISABLED_DEPENDENT_SETTING; 149 } 150 } 151 152 return AVAILABLE; 153 } 154 155 @Override getSliceHighlightMenuRes()156 public int getSliceHighlightMenuRes() { 157 return R.string.menu_key_notifications; 158 } 159 160 @Override onStart()161 public void onStart() { 162 mContext.getContentResolver().registerContentObserver( 163 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), 164 false /* notifyForDescendants */, mContentObserver); 165 } 166 167 @Override onStop()168 public void onStop() { 169 mContext.getContentResolver().unregisterContentObserver(mContentObserver); 170 } 171 getEnforcedAdmin(int userId)172 private RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin(int userId) { 173 RestrictedLockUtils.EnforcedAdmin admin = 174 RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled( 175 mContext, KEYGUARD_DISABLE_SECURE_NOTIFICATIONS, userId); 176 if (admin != null) { 177 return admin; 178 } 179 admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled( 180 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, userId); 181 return admin; 182 } 183 getAllowPrivateNotifications(int userId)184 private boolean getAllowPrivateNotifications(int userId) { 185 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 186 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, userId) != 0 187 && getEnforcedAdmin(userId) == null; 188 } 189 getLockscreenNotificationsEnabled(int userId)190 private boolean getLockscreenNotificationsEnabled(int userId) { 191 return Settings.Secure.getIntForUser(mContext.getContentResolver(), 192 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, userId) != 0; 193 } 194 } 195