Home | History | Annotate | Download | only in notification
      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