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