ConfigureNotificationSettings.java revision 3e19fc5600f739e7f172fb9331cfc0f4a884d4ce
1/**
2 * Copyright (C) 2015 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
17package com.android.settings.notification;
18
19import android.content.ContentResolver;
20import android.content.Context;
21import android.database.ContentObserver;
22import android.net.Uri;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.UserHandle;
26import android.os.UserManager;
27import android.provider.Settings;
28import android.support.v7.preference.Preference;
29import android.support.v7.preference.Preference.OnPreferenceChangeListener;
30import android.support.v7.preference.TwoStatePreference;
31import android.util.Log;
32import com.android.internal.logging.MetricsProto.MetricsEvent;
33import com.android.internal.widget.LockPatternUtils;
34import com.android.settings.R;
35import com.android.settings.RestrictedListPreference.RestrictedItem;
36import com.android.settings.SettingsPreferenceFragment;
37import com.android.settings.Utils;
38import com.android.settingslib.RestrictedLockUtils;
39
40import java.util.ArrayList;
41
42import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
43import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
44import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
45
46public class ConfigureNotificationSettings extends SettingsPreferenceFragment {
47    private static final String TAG = "ConfigNotiSettings";
48
49    private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
50    private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications";
51    private static final String KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS =
52            "lock_screen_notifications_profile";
53
54    private final SettingsObserver mSettingsObserver = new SettingsObserver();
55
56    private Context mContext;
57
58    private TwoStatePreference mNotificationPulse;
59    private NotificationLockscreenPreference mLockscreen;
60    private NotificationLockscreenPreference mLockscreenProfile;
61    private boolean mSecure;
62    private boolean mSecureProfile;
63    private int mLockscreenSelectedValue;
64    private int mLockscreenSelectedValueProfile;
65    private int mProfileChallengeUserId;
66
67    @Override
68    protected int getMetricsCategory() {
69        return MetricsEvent.CONFIGURE_NOTIFICATION;
70    }
71
72    @Override
73    public void onCreate(Bundle savedInstanceState) {
74        super.onCreate(savedInstanceState);
75        mContext = getActivity();
76        mProfileChallengeUserId = Utils.getManagedProfileId(
77                UserManager.get(mContext), UserHandle.myUserId());
78        mSecure = new LockPatternUtils(getActivity()).isSecure(UserHandle.myUserId());
79        mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
80                && new LockPatternUtils(getActivity()).isSecure(mProfileChallengeUserId);
81
82        addPreferencesFromResource(R.xml.configure_notification_settings);
83
84        initPulse();
85        initLockscreenNotifications();
86
87        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
88            addPreferencesFromResource(R.xml.configure_notification_settings_profile);
89            initLockscreenNotificationsForProfile();
90        }
91
92    }
93
94    @Override
95    public void onResume() {
96        super.onResume();
97        mSettingsObserver.register(true);
98    }
99
100    @Override
101    public void onPause() {
102        super.onPause();
103        mSettingsObserver.register(false);
104    }
105
106    // === Pulse notification light ===
107
108    private void initPulse() {
109        mNotificationPulse =
110                (TwoStatePreference) getPreferenceScreen().findPreference(KEY_NOTIFICATION_PULSE);
111        if (mNotificationPulse == null) {
112            Log.i(TAG, "Preference not found: " + KEY_NOTIFICATION_PULSE);
113            return;
114        }
115        if (!getResources()
116                .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
117            getPreferenceScreen().removePreference(mNotificationPulse);
118        } else {
119            updatePulse();
120            mNotificationPulse.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
121                @Override
122                public boolean onPreferenceChange(Preference preference, Object newValue) {
123                    final boolean val = (Boolean)newValue;
124                    return Settings.System.putInt(getContentResolver(),
125                            Settings.System.NOTIFICATION_LIGHT_PULSE,
126                            val ? 1 : 0);
127                }
128            });
129        }
130    }
131
132    private void updatePulse() {
133        if (mNotificationPulse == null) {
134            return;
135        }
136        try {
137            mNotificationPulse.setChecked(Settings.System.getInt(getContentResolver(),
138                    Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
139        } catch (Settings.SettingNotFoundException snfe) {
140            Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
141        }
142    }
143
144    private void initLockscreenNotifications() {
145        mLockscreen = (NotificationLockscreenPreference) getPreferenceScreen().findPreference(
146                KEY_LOCK_SCREEN_NOTIFICATIONS);
147        if (mLockscreen == null) {
148            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS);
149            return;
150        }
151
152        ArrayList<CharSequence> entries = new ArrayList<>();
153        ArrayList<CharSequence> values = new ArrayList<>();
154        entries.add(getString(R.string.lock_screen_notifications_summary_disable));
155        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable));
156
157        String summaryShowEntry = getString(R.string.lock_screen_notifications_summary_show);
158        String summaryShowEntryValue = Integer.toString(
159                R.string.lock_screen_notifications_summary_show);
160        entries.add(summaryShowEntry);
161        values.add(summaryShowEntryValue);
162        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
163                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
164
165        if (mSecure) {
166            String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
167            String summaryHideEntryValue = Integer.toString(
168                    R.string.lock_screen_notifications_summary_hide);
169            entries.add(summaryHideEntry);
170            values.add(summaryHideEntryValue);
171            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
172                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
173        }
174
175        mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()]));
176        mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()]));
177        updateLockscreenNotifications();
178        if (mLockscreen.getEntries().length > 1) {
179            mLockscreen.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
180                @Override
181                public boolean onPreferenceChange(Preference preference, Object newValue) {
182                    final int val = Integer.parseInt((String) newValue);
183                    if (val == mLockscreenSelectedValue) {
184                        return false;
185                    }
186                    final boolean enabled =
187                            val != R.string.lock_screen_notifications_summary_disable;
188                    final boolean show = val == R.string.lock_screen_notifications_summary_show;
189                    Settings.Secure.putInt(getContentResolver(),
190                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
191                    Settings.Secure.putInt(getContentResolver(),
192                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
193                    mLockscreenSelectedValue = val;
194                    return true;
195                }
196            });
197        } else {
198            // There is one or less option for the user, disable the drop down.
199            mLockscreen.setEnabled(false);
200        }
201    }
202
203    // === Lockscreen (public / private) notifications ===
204    private void initLockscreenNotificationsForProfile() {
205        mLockscreenProfile = (NotificationLockscreenPreference) getPreferenceScreen()
206                .findPreference(KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
207        if (mLockscreenProfile == null) {
208            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
209            return;
210        }
211
212        ArrayList<CharSequence> entries = new ArrayList<>();
213        ArrayList<CharSequence> values = new ArrayList<>();
214        entries.add(getString(R.string.lock_screen_notifications_summary_disable_profile));
215        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable_profile));
216
217        String summaryShowEntry = getString(
218                R.string.lock_screen_notifications_summary_show_profile);
219        String summaryShowEntryValue = Integer.toString(
220                R.string.lock_screen_notifications_summary_show_profile);
221        entries.add(summaryShowEntry);
222        values.add(summaryShowEntryValue);
223        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
224                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
225
226        if (mSecureProfile) {
227            String summaryHideEntry = getString(
228                    R.string.lock_screen_notifications_summary_hide_profile);
229            String summaryHideEntryValue = Integer.toString(
230                    R.string.lock_screen_notifications_summary_hide_profile);
231            entries.add(summaryHideEntry);
232            values.add(summaryHideEntryValue);
233            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
234                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
235        }
236
237        mLockscreenProfile.setEntries(entries.toArray(new CharSequence[entries.size()]));
238        mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
239        updateLockscreenNotificationsForProfile();
240        if (mLockscreenProfile.getEntries().length > 1) {
241            mLockscreenProfile.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
242                @Override
243                public boolean onPreferenceChange(Preference preference, Object newValue) {
244                    final int val = Integer.parseInt((String) newValue);
245                    if (val == mLockscreenSelectedValueProfile) {
246                        return false;
247                    }
248                    final boolean enabled =
249                            val != R.string.lock_screen_notifications_summary_disable_profile;
250                    final boolean show =
251                            val == R.string.lock_screen_notifications_summary_show_profile;
252                    Settings.Secure.putIntForUser(getContentResolver(),
253                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
254                            show ? 1 : 0, mProfileChallengeUserId);
255                    Settings.Secure.putIntForUser(getContentResolver(),
256                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
257                            enabled ? 1 : 0, mProfileChallengeUserId);
258                    mLockscreenSelectedValueProfile = val;
259                    return true;
260                }
261            });
262        } else {
263            // There is one or less option for the user, disable the drop down.
264            mLockscreenProfile.setEnabled(false);
265        }
266    }
267
268    private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
269            CharSequence entryValue, int keyguardNotificationFeatures) {
270        EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
271                mContext, keyguardNotificationFeatures, UserHandle.myUserId());
272        if (admin != null) {
273            RestrictedItem item = new RestrictedItem(entry, entryValue, admin);
274            mLockscreen.addRestrictedItem(item);
275        }
276        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
277            EnforcedAdmin profileAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
278                    mContext, keyguardNotificationFeatures, mProfileChallengeUserId);
279            if (profileAdmin != null) {
280                RestrictedItem item = new RestrictedItem(entry, entryValue, profileAdmin);
281                mLockscreenProfile.addRestrictedItem(item);
282            }
283        }
284    }
285
286    private void updateLockscreenNotifications() {
287        if (mLockscreen == null) {
288            return;
289        }
290        final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId());
291        final boolean allowPrivate = !mSecure
292                || getLockscreenAllowPrivateNotifications(UserHandle.myUserId());
293        mLockscreenSelectedValue = !enabled ? R.string.lock_screen_notifications_summary_disable :
294                allowPrivate ? R.string.lock_screen_notifications_summary_show :
295                R.string.lock_screen_notifications_summary_hide;
296        mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
297    }
298
299    private void updateLockscreenNotificationsForProfile() {
300        if (mProfileChallengeUserId == UserHandle.USER_NULL) {
301            return;
302        }
303        if (mLockscreenProfile == null) {
304            return;
305        }
306        final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId);
307        final boolean allowPrivate = !mSecureProfile
308                || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId);
309        mLockscreenSelectedValueProfile = !enabled
310                ? R.string.lock_screen_notifications_summary_disable_profile
311                        : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile
312                                : R.string.lock_screen_notifications_summary_hide_profile);
313        mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
314    }
315
316    private boolean getLockscreenNotificationsEnabled(int userId) {
317        return Settings.Secure.getIntForUser(getContentResolver(),
318                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
319    }
320
321    private boolean getLockscreenAllowPrivateNotifications(int userId) {
322        return Settings.Secure.getIntForUser(getContentResolver(),
323                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
324    }
325
326
327    // === Callbacks ===
328
329    private final class SettingsObserver extends ContentObserver {
330        private final Uri NOTIFICATION_LIGHT_PULSE_URI =
331                Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
332        private final Uri LOCK_SCREEN_PRIVATE_URI =
333                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
334        private final Uri LOCK_SCREEN_SHOW_URI =
335                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
336
337        public SettingsObserver() {
338            super(new Handler());
339        }
340
341        public void register(boolean register) {
342            final ContentResolver cr = getContentResolver();
343            if (register) {
344                cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this);
345                cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this);
346                cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this);
347            } else {
348                cr.unregisterContentObserver(this);
349            }
350        }
351
352        @Override
353        public void onChange(boolean selfChange, Uri uri) {
354            super.onChange(selfChange, uri);
355            if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
356                updatePulse();
357            }
358            if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) {
359                updateLockscreenNotifications();
360                if (mProfileChallengeUserId != UserHandle.USER_NULL) {
361                    updateLockscreenNotificationsForProfile();
362                }
363            }
364        }
365    }
366}
367