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