ConfigureNotificationSettings.java revision af67c3b57677d7680d094575a85ad160f739dfaf
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
79        final LockPatternUtils utils = new LockPatternUtils(getActivity());
80        final boolean isUnified =
81                !utils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId);
82
83        mSecure = utils.isSecure(UserHandle.myUserId());
84        mSecureProfile = (mProfileChallengeUserId != UserHandle.USER_NULL)
85                && (utils.isSecure(mProfileChallengeUserId) || (isUnified && mSecure));
86
87        addPreferencesFromResource(R.xml.configure_notification_settings);
88
89        initPulse();
90        initLockscreenNotifications();
91
92        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
93            addPreferencesFromResource(R.xml.configure_notification_settings_profile);
94            initLockscreenNotificationsForProfile();
95        }
96
97    }
98
99    @Override
100    public void onResume() {
101        super.onResume();
102        mSettingsObserver.register(true);
103    }
104
105    @Override
106    public void onPause() {
107        super.onPause();
108        mSettingsObserver.register(false);
109    }
110
111    // === Pulse notification light ===
112
113    private void initPulse() {
114        mNotificationPulse =
115                (TwoStatePreference) getPreferenceScreen().findPreference(KEY_NOTIFICATION_PULSE);
116        if (mNotificationPulse == null) {
117            Log.i(TAG, "Preference not found: " + KEY_NOTIFICATION_PULSE);
118            return;
119        }
120        if (!getResources()
121                .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
122            getPreferenceScreen().removePreference(mNotificationPulse);
123        } else {
124            updatePulse();
125            mNotificationPulse.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
126                @Override
127                public boolean onPreferenceChange(Preference preference, Object newValue) {
128                    final boolean val = (Boolean)newValue;
129                    return Settings.System.putInt(getContentResolver(),
130                            Settings.System.NOTIFICATION_LIGHT_PULSE,
131                            val ? 1 : 0);
132                }
133            });
134        }
135    }
136
137    private void updatePulse() {
138        if (mNotificationPulse == null) {
139            return;
140        }
141        try {
142            mNotificationPulse.setChecked(Settings.System.getInt(getContentResolver(),
143                    Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
144        } catch (Settings.SettingNotFoundException snfe) {
145            Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
146        }
147    }
148
149    private void initLockscreenNotifications() {
150        mLockscreen = (NotificationLockscreenPreference) getPreferenceScreen().findPreference(
151                KEY_LOCK_SCREEN_NOTIFICATIONS);
152        if (mLockscreen == null) {
153            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS);
154            return;
155        }
156
157        ArrayList<CharSequence> entries = new ArrayList<>();
158        ArrayList<CharSequence> values = new ArrayList<>();
159        entries.add(getString(R.string.lock_screen_notifications_summary_disable));
160        values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable));
161
162        String summaryShowEntry = getString(R.string.lock_screen_notifications_summary_show);
163        String summaryShowEntryValue = Integer.toString(
164                R.string.lock_screen_notifications_summary_show);
165        entries.add(summaryShowEntry);
166        values.add(summaryShowEntryValue);
167        setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue,
168                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
169
170        if (mSecure) {
171            String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide);
172            String summaryHideEntryValue = Integer.toString(
173                    R.string.lock_screen_notifications_summary_hide);
174            entries.add(summaryHideEntry);
175            values.add(summaryHideEntryValue);
176            setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue,
177                    KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
178        }
179
180        mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()]));
181        mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()]));
182        updateLockscreenNotifications();
183        if (mLockscreen.getEntries().length > 1) {
184            mLockscreen.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
185                @Override
186                public boolean onPreferenceChange(Preference preference, Object newValue) {
187                    final int val = Integer.parseInt((String) newValue);
188                    if (val == mLockscreenSelectedValue) {
189                        return false;
190                    }
191                    final boolean enabled =
192                            val != R.string.lock_screen_notifications_summary_disable;
193                    final boolean show = val == R.string.lock_screen_notifications_summary_show;
194                    Settings.Secure.putInt(getContentResolver(),
195                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
196                    Settings.Secure.putInt(getContentResolver(),
197                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
198                    mLockscreenSelectedValue = val;
199                    return true;
200                }
201            });
202        } else {
203            // There is one or less option for the user, disable the drop down.
204            mLockscreen.setEnabled(false);
205        }
206    }
207
208    // === Lockscreen (public / private) notifications ===
209    private void initLockscreenNotificationsForProfile() {
210        mLockscreenProfile = (NotificationLockscreenPreference) getPreferenceScreen()
211                .findPreference(KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
212        if (mLockscreenProfile == null) {
213            Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_PROFILE_NOTIFICATIONS);
214            return;
215        }
216        mLockscreenProfile.setUserId(mProfileChallengeUserId);
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.setEntries(entries.toArray(new CharSequence[entries.size()]));
243        mLockscreenProfile.setEntryValues(values.toArray(new CharSequence[values.size()]));
244        // Work profile does not support this settings as we do not have a policy to enforce it yet
245        mLockscreenProfile.setRemoteInputCheckBoxEnabled(false);
246        updateLockscreenNotificationsForProfile();
247        if (mLockscreenProfile.getEntries().length > 1) {
248            mLockscreenProfile.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
249                @Override
250                public boolean onPreferenceChange(Preference preference, Object newValue) {
251                    final int val = Integer.parseInt((String) newValue);
252                    if (val == mLockscreenSelectedValueProfile) {
253                        return false;
254                    }
255                    final boolean enabled =
256                            val != R.string.lock_screen_notifications_summary_disable_profile;
257                    final boolean show =
258                            val == R.string.lock_screen_notifications_summary_show_profile;
259                    Settings.Secure.putIntForUser(getContentResolver(),
260                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
261                            show ? 1 : 0, mProfileChallengeUserId);
262                    Settings.Secure.putIntForUser(getContentResolver(),
263                            Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
264                            enabled ? 1 : 0, mProfileChallengeUserId);
265                    mLockscreenSelectedValueProfile = val;
266                    return true;
267                }
268            });
269        } else {
270            // There is one or less option for the user, disable the drop down.
271            mLockscreenProfile.setEnabled(false);
272        }
273    }
274
275    private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
276            CharSequence entryValue, int keyguardNotificationFeatures) {
277        EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
278                mContext, keyguardNotificationFeatures, UserHandle.myUserId());
279        if (admin != null) {
280            RestrictedItem item = new RestrictedItem(entry, entryValue, admin);
281            mLockscreen.addRestrictedItem(item);
282        }
283        if (mProfileChallengeUserId != UserHandle.USER_NULL) {
284            EnforcedAdmin profileAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(
285                    mContext, keyguardNotificationFeatures, mProfileChallengeUserId);
286            if (profileAdmin != null) {
287                RestrictedItem item = new RestrictedItem(entry, entryValue, profileAdmin);
288                mLockscreenProfile.addRestrictedItem(item);
289            }
290        }
291    }
292
293    private void updateLockscreenNotifications() {
294        if (mLockscreen == null) {
295            return;
296        }
297        final boolean enabled = getLockscreenNotificationsEnabled(UserHandle.myUserId());
298        final boolean allowPrivate = !mSecure
299                || getLockscreenAllowPrivateNotifications(UserHandle.myUserId());
300        mLockscreenSelectedValue = !enabled ? R.string.lock_screen_notifications_summary_disable :
301                allowPrivate ? R.string.lock_screen_notifications_summary_show :
302                R.string.lock_screen_notifications_summary_hide;
303        mLockscreen.setValue(Integer.toString(mLockscreenSelectedValue));
304    }
305
306    private void updateLockscreenNotificationsForProfile() {
307        if (mProfileChallengeUserId == UserHandle.USER_NULL) {
308            return;
309        }
310        if (mLockscreenProfile == null) {
311            return;
312        }
313        final boolean enabled = getLockscreenNotificationsEnabled(mProfileChallengeUserId);
314        final boolean allowPrivate = !mSecureProfile
315                || getLockscreenAllowPrivateNotifications(mProfileChallengeUserId);
316        mLockscreenSelectedValueProfile = !enabled
317                ? R.string.lock_screen_notifications_summary_disable_profile
318                        : (allowPrivate ? R.string.lock_screen_notifications_summary_show_profile
319                                : R.string.lock_screen_notifications_summary_hide_profile);
320        mLockscreenProfile.setValue(Integer.toString(mLockscreenSelectedValueProfile));
321    }
322
323    private boolean getLockscreenNotificationsEnabled(int userId) {
324        return Settings.Secure.getIntForUser(getContentResolver(),
325                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userId) != 0;
326    }
327
328    private boolean getLockscreenAllowPrivateNotifications(int userId) {
329        return Settings.Secure.getIntForUser(getContentResolver(),
330                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userId) != 0;
331    }
332
333
334    // === Callbacks ===
335
336    private final class SettingsObserver extends ContentObserver {
337        private final Uri NOTIFICATION_LIGHT_PULSE_URI =
338                Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
339        private final Uri LOCK_SCREEN_PRIVATE_URI =
340                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
341        private final Uri LOCK_SCREEN_SHOW_URI =
342                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
343
344        public SettingsObserver() {
345            super(new Handler());
346        }
347
348        public void register(boolean register) {
349            final ContentResolver cr = getContentResolver();
350            if (register) {
351                cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this);
352                cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this);
353                cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this);
354            } else {
355                cr.unregisterContentObserver(this);
356            }
357        }
358
359        @Override
360        public void onChange(boolean selfChange, Uri uri) {
361            super.onChange(selfChange, uri);
362            if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
363                updatePulse();
364            }
365            if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) {
366                updateLockscreenNotifications();
367                if (mProfileChallengeUserId != UserHandle.USER_NULL) {
368                    updateLockscreenNotificationsForProfile();
369                }
370            }
371        }
372    }
373}
374