• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS;
20 
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.database.ContentObserver;
24 import android.net.Uri;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.provider.Settings;
28 
29 import androidx.annotation.NonNull;
30 import androidx.annotation.Nullable;
31 import androidx.lifecycle.Lifecycle;
32 import androidx.lifecycle.LifecycleEventObserver;
33 import androidx.lifecycle.LifecycleOwner;
34 import androidx.preference.Preference;
35 import androidx.preference.PreferenceScreen;
36 
37 import com.android.server.notification.Flags;
38 import com.android.settings.core.TogglePreferenceController;
39 
40 /**
41  * Controls the toggle that determines whether to hide seen notifications from the lock screen.
42  * Toggle for setting: Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS
43  */
44 public class LockScreenNotificationShowSeenController extends TogglePreferenceController
45         implements LifecycleEventObserver {
46 
47     // 0 is the default value for phones, we treat 0 as off as usage
48     private static final int UNSET_OFF = 0;
49     static final int ON = 1;
50     static final int OFF = 2;
51     @Nullable private Preference mPreference;
52     private final ContentResolver mContentResolver;
53 
54     final ContentObserver mContentObserver = new ContentObserver(
55             new Handler(Looper.getMainLooper())) {
56         @Override
57         public void onChange(boolean selfChange, @Nullable Uri uri) {
58             if (mPreference == null) return;
59             updateState(mPreference);
60         }
61     };
62 
LockScreenNotificationShowSeenController(@onNull Context context, @NonNull String preferenceKey)63     public LockScreenNotificationShowSeenController(@NonNull Context context,
64             @NonNull String preferenceKey) {
65         super(context, preferenceKey);
66         mContentResolver = context.getContentResolver();
67     }
68 
69     @Override
displayPreference(@onNull PreferenceScreen screen)70     public void displayPreference(@NonNull PreferenceScreen screen) {
71         super.displayPreference(screen);
72         mPreference = screen.findPreference(getPreferenceKey());
73     }
74 
75     @Override
onStateChanged(@onNull LifecycleOwner lifecycleOwner, @NonNull Lifecycle.Event event)76     public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
77             @NonNull Lifecycle.Event event) {
78         if (event == Lifecycle.Event.ON_RESUME) {
79             mContentResolver.registerContentObserver(
80                     Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
81                     /* notifyForDescendants= */ false, mContentObserver);
82             mContentResolver.registerContentObserver(
83                     Settings.Secure.getUriFor(
84                             Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS),
85                     /* notifyForDescendants= */ false,
86                     mContentObserver
87             );
88         } else if (event == Lifecycle.Event.ON_PAUSE) {
89             mContentResolver.unregisterContentObserver(mContentObserver);
90         }
91     }
92 
93     @Override
updateState(@onNull Preference preference)94     public void updateState(@NonNull Preference preference) {
95         super.updateState(preference);
96         setChecked(lockScreenShowSeenNotifications());
97         preference.setVisible(isAvailable());
98     }
99 
100     @Override
getAvailabilityStatus()101     public int getAvailabilityStatus() {
102         if (Flags.notificationMinimalism()) {
103             if (!lockScreenShowNotification()) {
104                 return CONDITIONALLY_UNAVAILABLE;
105             }
106             // We want to show the switch when the lock screen notification minimalism flag is on.
107             return AVAILABLE;
108         }
109 
110         int setting = Settings.Secure.getInt(mContext.getContentResolver(),
111                 LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, UNSET_OFF);
112         if (setting == UNSET_OFF) {
113             // hide the setting if the minimalism flag is off, and the device is phone
114             // UNSET_OFF is the default value for phones
115             return CONDITIONALLY_UNAVAILABLE;
116         } else {
117             return AVAILABLE;
118         }
119     }
120 
121     /**
122      * @return Whether showing notifications on the lockscreen is enabled.
123      */
lockScreenShowNotification()124     private boolean lockScreenShowNotification() {
125         return Settings.Secure.getInt(mContext.getContentResolver(),
126                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, OFF) == ON;
127     }
128 
129     @Override
isChecked()130     public boolean isChecked() {
131         return lockScreenShowSeenNotifications();
132     }
133 
134     /**
135      * @return whether to show seen notifications on lockscreen
136      */
lockScreenShowSeenNotifications()137     private boolean lockScreenShowSeenNotifications() {
138         // UNSET_OFF is the default value for phone, which is equivalent to off in effect
139         // (show seen notification)
140         return Settings.Secure.getInt(mContext.getContentResolver(),
141                 Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, UNSET_OFF) != ON;
142     }
143 
144     @Override
setChecked(boolean isChecked)145     public boolean setChecked(boolean isChecked) {
146         return Settings.Secure.putInt(mContext.getContentResolver(),
147                 Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, (isChecked ? OFF : ON));
148     }
149 
150     @Override
getSliceHighlightMenuRes()151     public int getSliceHighlightMenuRes() {
152         // not needed because Sliceable is deprecated
153         return NO_RES;
154     }
155 }
156