1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.internal.notification;
16 
17 import static android.app.admin.DevicePolicyResources.Strings.Core.NOTIFICATION_CHANNEL_DEVICE_ADMIN;
18 
19 import android.app.INotificationManager;
20 import android.app.NotificationChannel;
21 import android.app.NotificationManager;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.Context;
24 import android.content.pm.ParceledListSlice;
25 import android.media.AudioAttributes;
26 import android.os.RemoteException;
27 
28 import com.android.internal.R;
29 
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.List;
33 
34 // Manages the NotificationChannels used by the frameworks itself.
35 public class SystemNotificationChannels {
36     /**
37      * @deprecated Legacy system channel, which is no longer used,
38      */
39     @Deprecated public static String VIRTUAL_KEYBOARD  = "VIRTUAL_KEYBOARD";
40     public static String PHYSICAL_KEYBOARD = "PHYSICAL_KEYBOARD";
41     public static String SECURITY = "SECURITY";
42     public static String CAR_MODE = "CAR_MODE";
43     public static String ACCOUNT = "ACCOUNT";
44     public static String DEVELOPER = "DEVELOPER";
45     public static String DEVELOPER_IMPORTANT = "DEVELOPER_IMPORTANT";
46     public static String UPDATES = "UPDATES";
47     public static String NETWORK_STATUS = "NETWORK_STATUS";
48     public static String NETWORK_ALERTS = "NETWORK_ALERTS";
49     public static String NETWORK_AVAILABLE = "NETWORK_AVAILABLE";
50     public static String VPN = "VPN";
51     /**
52      * @deprecated Legacy device admin channel with low importance which is no longer used,
53      *  Use the high importance {@link #DEVICE_ADMIN} channel instead.
54      */
55     @Deprecated public static String DEVICE_ADMIN_DEPRECATED = "DEVICE_ADMIN";
56     public static String DEVICE_ADMIN = "DEVICE_ADMIN_ALERTS";
57     public static String ALERTS = "ALERTS";
58     public static String RETAIL_MODE = "RETAIL_MODE";
59     public static String USB = "USB";
60     public static String FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
61     public static String HEAVY_WEIGHT_APP = "HEAVY_WEIGHT_APP";
62     /**
63      * @deprecated Legacy system changes channel with low importance which is no longer used,
64      *  Use the default importance {@link #SYSTEM_CHANGES} channel instead.
65      */
66     @Deprecated public static String SYSTEM_CHANGES_DEPRECATED = "SYSTEM_CHANGES";
67     public static String SYSTEM_CHANGES = "SYSTEM_CHANGES_ALERTS";
68     public static String DO_NOT_DISTURB = "DO_NOT_DISTURB";
69     public static String ACCESSIBILITY_MAGNIFICATION = "ACCESSIBILITY_MAGNIFICATION";
70     public static String ACCESSIBILITY_SECURITY_POLICY = "ACCESSIBILITY_SECURITY_POLICY";
71     public static String ABUSIVE_BACKGROUND_APPS = "ABUSIVE_BACKGROUND_APPS";
72 
createAll(Context context)73     public static void createAll(Context context) {
74         final NotificationManager nm = context.getSystemService(NotificationManager.class);
75         List<NotificationChannel> channelsList = new ArrayList<NotificationChannel>();
76         final NotificationChannel physicalKeyboardChannel = new NotificationChannel(
77                 PHYSICAL_KEYBOARD,
78                 context.getString(R.string.notification_channel_physical_keyboard),
79                 NotificationManager.IMPORTANCE_LOW);
80         physicalKeyboardChannel.setBlockable(true);
81         channelsList.add(physicalKeyboardChannel);
82 
83         final NotificationChannel security = new NotificationChannel(
84                 SECURITY,
85                 context.getString(R.string.notification_channel_security),
86                 NotificationManager.IMPORTANCE_LOW);
87         channelsList.add(security);
88 
89         final NotificationChannel car = new NotificationChannel(
90                 CAR_MODE,
91                 context.getString(R.string.notification_channel_car_mode),
92                 NotificationManager.IMPORTANCE_LOW);
93         car.setBlockable(true);
94         channelsList.add(car);
95 
96         channelsList.add(newAccountChannel(context));
97 
98         final NotificationChannel developer = new NotificationChannel(
99                 DEVELOPER,
100                 context.getString(R.string.notification_channel_developer),
101                 NotificationManager.IMPORTANCE_LOW);
102         developer.setBlockable(true);
103         channelsList.add(developer);
104 
105         final NotificationChannel developerImportant = new NotificationChannel(
106                 DEVELOPER_IMPORTANT,
107                 context.getString(R.string.notification_channel_developer_important),
108                 NotificationManager.IMPORTANCE_HIGH);
109         developer.setBlockable(true);
110         channelsList.add(developerImportant);
111 
112         final NotificationChannel updates = new NotificationChannel(
113                 UPDATES,
114                 context.getString(R.string.notification_channel_updates),
115                 NotificationManager.IMPORTANCE_LOW);
116         channelsList.add(updates);
117 
118         final NotificationChannel network = new NotificationChannel(
119                 NETWORK_STATUS,
120                 context.getString(R.string.notification_channel_network_status),
121                 NotificationManager.IMPORTANCE_LOW);
122         network.setBlockable(true);
123         channelsList.add(network);
124 
125         final NotificationChannel networkAlertsChannel = new NotificationChannel(
126                 NETWORK_ALERTS,
127                 context.getString(R.string.notification_channel_network_alerts),
128                 NotificationManager.IMPORTANCE_HIGH);
129         networkAlertsChannel.setBlockable(true);
130         channelsList.add(networkAlertsChannel);
131 
132         final NotificationChannel networkAvailable = new NotificationChannel(
133                 NETWORK_AVAILABLE,
134                 context.getString(R.string.notification_channel_network_available),
135                 NotificationManager.IMPORTANCE_LOW);
136         networkAvailable.setBlockable(true);
137         channelsList.add(networkAvailable);
138 
139         final NotificationChannel vpn = new NotificationChannel(
140                 VPN,
141                 context.getString(R.string.notification_channel_vpn),
142                 NotificationManager.IMPORTANCE_LOW);
143         channelsList.add(vpn);
144 
145         final NotificationChannel deviceAdmin = new NotificationChannel(
146                 DEVICE_ADMIN,
147                 getDeviceAdminNotificationChannelName(context),
148                 NotificationManager.IMPORTANCE_HIGH);
149         channelsList.add(deviceAdmin);
150 
151         final NotificationChannel alertsChannel = new NotificationChannel(
152                 ALERTS,
153                 context.getString(R.string.notification_channel_alerts),
154                 NotificationManager.IMPORTANCE_DEFAULT);
155         channelsList.add(alertsChannel);
156 
157         final NotificationChannel retail = new NotificationChannel(
158                 RETAIL_MODE,
159                 context.getString(R.string.notification_channel_retail_mode),
160                 NotificationManager.IMPORTANCE_LOW);
161         channelsList.add(retail);
162 
163         final NotificationChannel usb = new NotificationChannel(
164                 USB,
165                 context.getString(R.string.notification_channel_usb),
166                 NotificationManager.IMPORTANCE_MIN);
167         channelsList.add(usb);
168 
169         NotificationChannel foregroundChannel = new NotificationChannel(
170                 FOREGROUND_SERVICE,
171                 context.getString(R.string.notification_channel_foreground_service),
172                 NotificationManager.IMPORTANCE_LOW);
173         foregroundChannel.setBlockable(true);
174         channelsList.add(foregroundChannel);
175 
176         NotificationChannel heavyWeightChannel = new NotificationChannel(
177                 HEAVY_WEIGHT_APP,
178                 context.getString(R.string.notification_channel_heavy_weight_app),
179                 NotificationManager.IMPORTANCE_DEFAULT);
180         heavyWeightChannel.setShowBadge(false);
181         heavyWeightChannel.setSound(null, new AudioAttributes.Builder()
182                 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
183                 .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
184                 .build());
185         channelsList.add(heavyWeightChannel);
186 
187         NotificationChannel systemChanges = new NotificationChannel(SYSTEM_CHANGES,
188                 context.getString(R.string.notification_channel_system_changes),
189                 NotificationManager.IMPORTANCE_DEFAULT);
190         systemChanges.setSound(null, new AudioAttributes.Builder()
191                 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
192                 .setUsage(AudioAttributes.USAGE_NOTIFICATION)
193                 .build());
194         channelsList.add(systemChanges);
195 
196         NotificationChannel dndChanges = new NotificationChannel(DO_NOT_DISTURB,
197                 context.getString(R.string.notification_channel_do_not_disturb),
198                 NotificationManager.IMPORTANCE_LOW);
199         channelsList.add(dndChanges);
200 
201         final NotificationChannel newFeaturePrompt = new NotificationChannel(
202                 ACCESSIBILITY_MAGNIFICATION,
203                 context.getString(R.string.notification_channel_accessibility_magnification),
204                 NotificationManager.IMPORTANCE_HIGH);
205         newFeaturePrompt.setBlockable(true);
206         channelsList.add(newFeaturePrompt);
207 
208         final NotificationChannel accessibilitySecurityPolicyChannel = new NotificationChannel(
209                 ACCESSIBILITY_SECURITY_POLICY,
210                 context.getString(R.string.notification_channel_accessibility_security_policy),
211                 NotificationManager.IMPORTANCE_LOW);
212         channelsList.add(accessibilitySecurityPolicyChannel);
213 
214         final NotificationChannel abusiveBackgroundAppsChannel = new NotificationChannel(
215                 ABUSIVE_BACKGROUND_APPS,
216                 context.getString(R.string.notification_channel_abusive_bg_apps),
217                 NotificationManager.IMPORTANCE_LOW);
218         channelsList.add(abusiveBackgroundAppsChannel);
219 
220         nm.createNotificationChannels(channelsList);
221     }
222 
getDeviceAdminNotificationChannelName(Context context)223     private static String getDeviceAdminNotificationChannelName(Context context) {
224         DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
225         return dpm.getResources().getString(NOTIFICATION_CHANNEL_DEVICE_ADMIN,
226                 () -> context.getString(R.string.notification_channel_device_admin));
227     }
228 
229     /** Remove notification channels which are no longer used */
removeDeprecated(Context context)230     public static void removeDeprecated(Context context) {
231         final NotificationManager nm = context.getSystemService(NotificationManager.class);
232         nm.deleteNotificationChannel(VIRTUAL_KEYBOARD);
233         nm.deleteNotificationChannel(DEVICE_ADMIN_DEPRECATED);
234         nm.deleteNotificationChannel(SYSTEM_CHANGES_DEPRECATED);
235     }
236 
createAccountChannelForPackage(String pkg, int uid, Context context)237     public static void createAccountChannelForPackage(String pkg, int uid, Context context) {
238         final INotificationManager iNotificationManager = NotificationManager.getService();
239         try {
240             iNotificationManager.createNotificationChannelsForPackage(pkg, uid,
241                     new ParceledListSlice(Arrays.asList(newAccountChannel(context))));
242         } catch (RemoteException e) {
243             throw e.rethrowFromSystemServer();
244         }
245     }
246 
newAccountChannel(Context context)247     private static NotificationChannel newAccountChannel(Context context) {
248         return new NotificationChannel(
249                 ACCOUNT,
250                 context.getString(R.string.notification_channel_account),
251                 NotificationManager.IMPORTANCE_LOW);
252     }
253 
SystemNotificationChannels()254     private SystemNotificationChannels() {}
255 }
256