• 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.app;
18 
19 import static android.app.NotificationChannel.NEWS_ID;
20 import static android.app.NotificationChannel.PROMOTIONS_ID;
21 import static android.app.NotificationChannel.RECS_ID;
22 import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
23 import static android.app.NotificationManager.IMPORTANCE_LOW;
24 import static android.app.NotificationManager.IMPORTANCE_NONE;
25 
26 import static com.android.server.notification.Flags.notificationHideUnusedChannels;
27 
28 import android.app.NotificationChannel;
29 import android.app.NotificationChannelGroup;
30 import android.app.settings.SettingsEnums;
31 import android.content.Context;
32 import android.graphics.drawable.Drawable;
33 import android.os.AsyncTask;
34 import android.os.Bundle;
35 import android.provider.Settings;
36 import android.service.notification.Flags;
37 import android.text.TextUtils;
38 
39 import androidx.annotation.NonNull;
40 import androidx.annotation.Nullable;
41 import androidx.preference.Preference;
42 import androidx.preference.PreferenceCategory;
43 import androidx.preference.PreferenceGroup;
44 import androidx.preference.TwoStatePreference;
45 
46 import com.android.settings.R;
47 import com.android.settings.Utils;
48 import com.android.settings.applications.AppInfoBase;
49 import com.android.settings.core.SubSettingLauncher;
50 import com.android.settings.notification.NotificationBackend;
51 import com.android.settingslib.PrimarySwitchPreference;
52 import com.android.settingslib.RestrictedSwitchPreference;
53 
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.List;
57 
58 public class BundleListPreferenceController extends NotificationPreferenceController {
59 
60     private static final String KEY = "bundles";
61 
BundleListPreferenceController(Context context, NotificationBackend backend)62     public BundleListPreferenceController(Context context, NotificationBackend backend) {
63         super(context, backend);
64     }
65 
66     @Override
getPreferenceKey()67     public String getPreferenceKey() {
68         return KEY;
69     }
70 
71     @Override
isAvailable()72     public boolean isAvailable() {
73         if (!Flags.notificationClassification()) {
74             return false;
75         }
76         if (mAppRow == null) {
77             return false;
78         }
79         if (mAppRow.banned || mAppRow.lockedImportance || mAppRow.systemApp) {
80             return false;
81         }
82         return true;
83     }
84 
85     @Override
isIncludedInFilter()86     boolean isIncludedInFilter() {
87         return false;
88     }
89 
90     @Override
updateState(Preference preference)91     public void updateState(Preference preference) {
92         PreferenceCategory category = (PreferenceCategory) preference;
93 
94         NotificationChannel promos = mBackend.getChannel(mAppRow.pkg, mAppRow.uid, PROMOTIONS_ID);
95         if (promos != null) {
96             createOrUpdatePrefForChannel(category, promos);
97         }
98         NotificationChannel recs = mBackend.getChannel(mAppRow.pkg, mAppRow.uid, RECS_ID);
99         if (recs != null) {
100             createOrUpdatePrefForChannel(category, recs);
101         }
102         NotificationChannel social = mBackend.getChannel(mAppRow.pkg, mAppRow.uid, SOCIAL_MEDIA_ID);
103         if (social != null) {
104             createOrUpdatePrefForChannel(category, social);
105         }
106         NotificationChannel news = mBackend.getChannel(mAppRow.pkg, mAppRow.uid, NEWS_ID);
107         if (news != null) {
108             createOrUpdatePrefForChannel(category, news);
109         }
110 
111         int preferenceCount = ((PreferenceGroup) preference).getPreferenceCount();
112         if (preferenceCount == 0) {
113             preference.setVisible(false);
114         }
115     }
116 
117     @NonNull
createOrUpdatePrefForChannel( @onNull PreferenceGroup groupPrefGroup, NotificationChannel channel)118     private void createOrUpdatePrefForChannel(
119             @NonNull PreferenceGroup groupPrefGroup, NotificationChannel channel) {
120         int preferenceCount = groupPrefGroup.getPreferenceCount();
121         for (int i = 0; i < preferenceCount; i++) {
122             Preference preference = groupPrefGroup.getPreference(i);
123             if (channel.getId().equals(preference.getKey())) {
124                 updateSingleChannelPrefs((PrimarySwitchPreference) preference, channel);
125                 return;
126             }
127         }
128         PrimarySwitchPreference channelPref = new PrimarySwitchPreference(mContext);
129         channelPref.setKey(channel.getId());
130         updateSingleChannelPrefs(channelPref, channel);
131         groupPrefGroup.addPreference(channelPref);
132     }
133 
134     /** Update the properties of the channel preference with the values from the channel object. */
updateSingleChannelPrefs(@onNull final PrimarySwitchPreference channelPref, @NonNull final NotificationChannel channel)135     private void updateSingleChannelPrefs(@NonNull final PrimarySwitchPreference channelPref,
136             @NonNull final NotificationChannel channel) {
137         channelPref.setSwitchEnabled(mAdmin == null);
138         if (channel.getImportance() > IMPORTANCE_LOW) {
139             channelPref.setIcon(getAlertingIcon());
140         } else {
141             channelPref.setIcon(mContext.getDrawable(R.drawable.empty_icon));
142         }
143         channelPref.setIconSize(PrimarySwitchPreference.ICON_SIZE_SMALL);
144         channelPref.setTitle(channel.getName());
145         channelPref.setSummary(NotificationBackend.getSentSummary(
146                 mContext, mAppRow.sentByChannel.get(channel.getId()), false));
147         channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
148         Bundle channelArgs = new Bundle();
149         channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mAppRow.uid);
150         channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mAppRow.pkg);
151         channelArgs.putString(Settings.EXTRA_CHANNEL_ID, channel.getId());
152         channelPref.setIntent(new SubSettingLauncher(mContext)
153                 .setDestination(ChannelNotificationSettings.class.getName())
154                 .setArguments(channelArgs)
155                 .setTitleRes(R.string.notification_channel_title)
156                 .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_APP_NOTIFICATION)
157                 .toIntent());
158 
159         channelPref.setOnPreferenceChangeListener(
160                 (preference, o) -> {
161                     boolean value = (Boolean) o;
162                     int importance = value
163                             ? Math.max(channel.getOriginalImportance(), IMPORTANCE_LOW)
164                             : IMPORTANCE_NONE;
165                     channel.setImportance(importance);
166                     channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
167                     PrimarySwitchPreference channelPref1 = (PrimarySwitchPreference) preference;
168                     channelPref1.setIcon(R.drawable.empty_icon);
169                     if (channel.getImportance() > IMPORTANCE_LOW) {
170                         channelPref1.setIcon(getAlertingIcon());
171                     }
172                     mBackend.updateChannel(mAppRow.pkg, mAppRow.uid, channel);
173 
174                     return true;
175                 });
176     }
177 
getAlertingIcon()178     private Drawable getAlertingIcon() {
179         Drawable icon = mContext.getDrawable(R.drawable.ic_notifications_alert);
180         icon.setTintList(Utils.getColorAccent(mContext));
181         return icon;
182     }
183 }
184