1 /*
2  * Copyright (C) 2017 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.app;
18 
19 import static android.app.NotificationManager.IMPORTANCE_LOW;
20 import static android.app.NotificationManager.IMPORTANCE_NONE;
21 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
22 
23 import android.app.NotificationChannel;
24 import android.app.NotificationManager;
25 import android.content.Context;
26 import android.widget.Switch;
27 
28 import androidx.preference.Preference;
29 
30 import com.android.settings.R;
31 import com.android.settings.core.PreferenceControllerMixin;
32 import com.android.settings.notification.NotificationBackend;
33 import com.android.settings.widget.SettingsMainSwitchPreference;
34 import com.android.settingslib.widget.OnMainSwitchChangeListener;
35 
36 public class BlockPreferenceController extends NotificationPreferenceController
37         implements PreferenceControllerMixin, OnMainSwitchChangeListener {
38 
39     private static final String KEY_BLOCK = "block";
40     private NotificationSettings.DependentFieldListener mDependentFieldListener;
41 
BlockPreferenceController(Context context, NotificationSettings.DependentFieldListener dependentFieldListener, NotificationBackend backend)42     public BlockPreferenceController(Context context,
43             NotificationSettings.DependentFieldListener dependentFieldListener,
44             NotificationBackend backend) {
45         super(context, backend);
46         mDependentFieldListener = dependentFieldListener;
47     }
48 
49     @Override
getPreferenceKey()50     public String getPreferenceKey() {
51         return KEY_BLOCK;
52     }
53 
54     @Override
isAvailable()55     public boolean isAvailable() {
56         if (mAppRow == null) {
57             return false;
58         }
59         if (mPreferenceFilter != null && !isIncludedInFilter()) {
60             return false;
61         }
62         return true;
63     }
64 
65     @Override
isIncludedInFilter()66     boolean isIncludedInFilter() {
67         return mPreferenceFilter.contains(NotificationChannel.EDIT_IMPORTANCE);
68     }
69 
updateState(Preference preference)70     public void updateState(Preference preference) {
71         SettingsMainSwitchPreference bar = (SettingsMainSwitchPreference) preference;
72         if (bar != null) {
73             String switchBarText = getSwitchBarText();
74             bar.setTitle(switchBarText);
75             bar.show();
76             try {
77                 bar.addOnSwitchChangeListener(this);
78             } catch (IllegalStateException e) {
79                 // an exception is thrown if you try to add the listener twice
80             }
81             bar.setDisabledByAdmin(mAdmin);
82 
83             if (mChannel != null && !isChannelBlockable()) {
84                 bar.setSwitchBarEnabled(false);
85             }
86 
87             if (mChannelGroup != null && !isChannelGroupBlockable()) {
88                 bar.setSwitchBarEnabled(false);
89             }
90 
91             if (mChannel == null && mAppRow.systemApp
92                     && (!mAppRow.banned || mAppRow.lockedImportance)) {
93                 bar.setSwitchBarEnabled(false);
94             }
95 
96             if (mChannel != null) {
97                 bar.setChecked(!mAppRow.banned
98                         && mChannel.getImportance() != NotificationManager.IMPORTANCE_NONE);
99             } else if (mChannelGroup != null) {
100                 bar.setChecked(!mAppRow.banned && !mChannelGroup.isBlocked());
101             } else {
102                 bar.setChecked(!mAppRow.banned);
103             }
104         }
105     }
106 
107     @Override
onSwitchChanged(Switch switchView, boolean isChecked)108     public void onSwitchChanged(Switch switchView, boolean isChecked) {
109         boolean blocked = !isChecked;
110         if (mChannel != null) {
111             final int originalImportance = mChannel.getImportance();
112             // setting the initial state of the switch in updateState() triggers this callback.
113             // It's always safe to override the importance if it's meant to be blocked or if
114             // it was blocked and we are unblocking it.
115             if (blocked || originalImportance == IMPORTANCE_NONE) {
116                 final int importance = blocked
117                         ? IMPORTANCE_NONE
118                         : isDefaultChannel()
119                                 ? IMPORTANCE_UNSPECIFIED
120                                 : Math.max(mChannel.getOriginalImportance(), IMPORTANCE_LOW);
121                 mChannel.setImportance(importance);
122                 saveChannel();
123             }
124             if (mBackend.onlyHasDefaultChannel(mAppRow.pkg, mAppRow.uid)) {
125                 if (mAppRow.banned != blocked) {
126                     mAppRow.banned = blocked;
127                     mBackend.setNotificationsEnabledForPackage(mAppRow.pkg, mAppRow.uid, !blocked);
128                 }
129             }
130         } else if (mChannelGroup != null) {
131             mChannelGroup.setBlocked(blocked);
132             mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, mChannelGroup);
133         } else if (mAppRow != null) {
134             mAppRow.banned = blocked;
135             mBackend.setNotificationsEnabledForPackage(mAppRow.pkg, mAppRow.uid, !blocked);
136         }
137         mDependentFieldListener.onFieldValueChanged();
138     }
139 
getSwitchBarText()140     String getSwitchBarText() {
141         if (mChannel != null) {
142             return mContext.getString(R.string.notification_content_block_title);
143         } else {
144             CharSequence fieldContextName;
145             if (mChannelGroup != null) {
146                 fieldContextName = mChannelGroup.getName();
147             } else {
148                 fieldContextName = mAppRow.label;
149             }
150             return mContext.getString(R.string.notification_app_switch_label, fieldContextName);
151         }
152     }
153 }
154