• 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 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 
LockScreenNotificationPreferenceController(Context context)66     public LockScreenNotificationPreferenceController(Context context) {
67         this(context, null, null, null);
68     }
69 
LockScreenNotificationPreferenceController(Context context, String settingKey, String workSettingCategoryKey, String workSettingKey)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
displayPreference(PreferenceScreen screen)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 
initLockScreenNotificationPrefDisplay()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 
initLockscreenNotificationPrefForProfile()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
getPreferenceKey()192     public String getPreferenceKey() {
193         return null;
194     }
195 
196     @Override
isAvailable()197     public boolean isAvailable() {
198         return false;
199     }
200 
201     @Override
onResume()202     public void onResume() {
203         if (mSettingObserver != null) {
204             mSettingObserver.register(mContext.getContentResolver(), true /* register */);
205         }
206     }
207 
208     @Override
onPause()209     public void onPause() {
210         if (mSettingObserver != null) {
211             mSettingObserver.register(mContext.getContentResolver(), false /* register */);
212         }
213     }
214 
215     @Override
onPreferenceChange(Preference preference, Object newValue)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 
setRestrictedIfNotificationFeaturesDisabled(CharSequence entry, CharSequence entryValue, int keyguardNotificationFeatures)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 
getSummaryResource()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 
updateLockscreenNotifications()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 
updateLockscreenNotificationsForProfile()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 
getLockscreenNotificationsEnabled(int userId)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 
getLockscreenAllowPrivateNotifications(int userId)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 
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 (mProfileChallengeUserId != UserHandle.USER_NULL) {
348                     updateLockscreenNotificationsForProfile();
349                 }
350             }
351         }
352     }
353 }
354