• 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.lockscreen;
18 
19 import static android.provider.Settings.Secure.LOCK_SCREEN_NOTIFICATION_MINIMALISM;
20 import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS;
21 
22 import android.content.ContentResolver;
23 import android.content.Context;
24 import android.database.ContentObserver;
25 import android.net.Uri;
26 import android.os.Handler;
27 import android.os.Looper;
28 import android.provider.Settings;
29 import android.widget.LinearLayout;
30 
31 import androidx.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 import androidx.lifecycle.Lifecycle;
34 import androidx.lifecycle.LifecycleEventObserver;
35 import androidx.lifecycle.LifecycleOwner;
36 import androidx.preference.PreferenceScreen;
37 
38 import com.android.server.notification.Flags;
39 import com.android.settings.R;
40 import com.android.settings.core.BasePreferenceController;
41 import com.android.settingslib.widget.IllustrationPreference;
42 import com.android.settingslib.widget.LayoutPreference;
43 
44 import java.util.HashMap;
45 import java.util.Map;
46 
47 public class MinimalismPreferenceController
48         extends BasePreferenceController
49         implements LifecycleEventObserver {
50 
51     private static final int LS_SHOW_NOTIF_ON = 1;
52     private static final int LS_SHOW_NOTIF_OFF = 0;
53     private static final int LS_MINIMALISM_OFF = 0;
54     private static final int LS_MINIMALISM_ON = 1;
55     private static final String KEY_MINIMALISM_PREFERENCE = "ls_minimalism";
56     private static final String KEY_FULL_LIST_ILLUSTRATION = "full_list_illustration";
57     private static final String KEY_COMPACT_ILLUSTRATION = "compact_illustration";
58     private static final Uri URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM =
59             Settings.Secure.getUriFor(LOCK_SCREEN_NOTIFICATION_MINIMALISM);
60     private static final Uri URI_LOCK_SCREEN_SHOW_NOTIFICATIONS =
61             Settings.Secure.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS);
62 
63     @Nullable private LayoutPreference mPreference;
64     private Map<Integer, LinearLayout> mButtons = new HashMap<>();
65     private Map<Integer, IllustrationPreference> mIllustrations = new HashMap<>();
66 
67     private final ContentResolver mContentResolver;
68 
69     final ContentObserver mContentObserver = new ContentObserver(
70             new Handler(Looper.getMainLooper())) {
71         @Override
72         public void onChange(boolean selfChange, @Nullable Uri uri) {
73             refreshState(uri);
74         }
75     };
76 
MinimalismPreferenceController(@onNull Context context, @NonNull String preferenceKey)77     public MinimalismPreferenceController(@NonNull Context context, @NonNull String preferenceKey) {
78         super(context, preferenceKey);
79         mContentResolver = context.getContentResolver();
80     }
81 
82     @Override
onStateChanged(@onNull LifecycleOwner lifecycleOwner, @NonNull Lifecycle.Event event)83     public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
84             @NonNull Lifecycle.Event event) {
85         if (event == Lifecycle.Event.ON_RESUME) {
86             mContentResolver.registerContentObserver(
87                     URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM,
88                     /* notifyForDescendants= */ false,
89                     mContentObserver
90             );
91             mContentResolver.registerContentObserver(
92                     URI_LOCK_SCREEN_SHOW_NOTIFICATIONS,
93                     /* notifyForDescendants= */ false,
94                     mContentObserver
95             );
96         } else if (event == Lifecycle.Event.ON_PAUSE) {
97             mContentResolver.unregisterContentObserver(mContentObserver);
98         }
99     }
100 
101     @Override
getAvailabilityStatus()102     public int getAvailabilityStatus() {
103         if (!Flags.notificationMinimalism()) {
104             return CONDITIONALLY_UNAVAILABLE;
105         }
106         if (!lockScreenShowNotification()) {
107             return CONDITIONALLY_UNAVAILABLE;
108         }
109         return AVAILABLE;
110     }
111 
112     /**
113      * @return Whether showing notifications on the lockscreen is enabled.
114      */
lockScreenShowNotification()115     private boolean lockScreenShowNotification() {
116         return Settings.Secure.getInt(
117                 mContext.getContentResolver(),
118                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
119                 LS_SHOW_NOTIF_OFF
120         ) == LS_SHOW_NOTIF_ON;
121     }
122 
123     @Override
displayPreference(@onNull PreferenceScreen screen)124     public void displayPreference(@NonNull PreferenceScreen screen) {
125         super.displayPreference(screen);
126         mPreference = screen.findPreference(KEY_MINIMALISM_PREFERENCE);
127 
128         mButtons = Map.ofEntries(
129                 Map.entry(LS_MINIMALISM_OFF,
130                         mPreference.findViewById(R.id.button_full)),
131                 Map.entry(LS_MINIMALISM_ON,
132                         mPreference.findViewById(R.id.button_compact))
133         );
134 
135         mIllustrations = Map.ofEntries(
136                 Map.entry(LS_MINIMALISM_OFF,
137                         screen.findPreference(KEY_FULL_LIST_ILLUSTRATION)),
138                 Map.entry(LS_MINIMALISM_ON,
139                         screen.findPreference(KEY_COMPACT_ILLUSTRATION))
140         );
141         mButtons.forEach((value, button) -> button.setOnClickListener(v ->
142                 Settings.Secure.putInt(
143                         mContext.getContentResolver(),
144                         Settings.Secure.LOCK_SCREEN_NOTIFICATION_MINIMALISM,
145                         value
146                 )
147         ));
148 
149         refreshState(URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM);
150     }
151 
highlightButton(int currentValue)152     private void highlightButton(int currentValue) {
153         mButtons.forEach((value, button) -> button.setSelected(currentValue == value));
154     }
155 
highlightIllustration(int currentValue)156     private void highlightIllustration(int currentValue) {
157         mIllustrations.forEach((value, preference)
158                 -> preference.setVisible(currentValue == value));
159     }
160 
getCurrentMinimalismValue()161     private int getCurrentMinimalismValue() {
162         return Settings.Secure.getInt(mContext.getContentResolver(),
163                 LOCK_SCREEN_NOTIFICATION_MINIMALISM, LS_MINIMALISM_ON);
164     }
165 
refreshState(@ullable Uri uri)166     private void refreshState(@Nullable Uri uri) {
167         if (mPreference == null) return;
168         if (URI_LOCK_SCREEN_SHOW_NOTIFICATIONS.equals(uri) && !lockScreenShowNotification()) {
169             // hide all preferences when showing notifications on lock screen is disabled
170             mIllustrations.forEach((value, preference)
171                     -> preference.setVisible(false));
172             mPreference.setVisible(false);
173         } else {
174             mPreference.setVisible(isAvailable());
175             int currentValue = getCurrentMinimalismValue();
176             highlightButton(currentValue);
177             highlightIllustration(currentValue);
178         }
179     }
180 }
181