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