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