1 /*
2  * Copyright (C) 2021 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.server.wifi;
18 
19 import static com.android.server.wifi.WifiService.NOTIFICATION_APM_ALERTS;
20 import static com.android.server.wifi.WifiService.NOTIFICATION_NETWORK_ALERTS;
21 import static com.android.server.wifi.WifiService.NOTIFICATION_NETWORK_AVAILABLE;
22 import static com.android.server.wifi.WifiService.NOTIFICATION_NETWORK_STATUS;
23 
24 import android.annotation.SuppressLint;
25 import android.app.Notification;
26 import android.app.NotificationChannel;
27 import android.app.NotificationManager;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.os.UserHandle;
31 import android.service.notification.StatusBarNotification;
32 import android.util.Log;
33 
34 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
35 import com.android.wifi.resources.R;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 /**
41  * Notification manager for Wifi. All notification will be sent to the current user.
42  */
43 public class WifiNotificationManager {
44     private static final String TAG = "WifiNotificationManager";
45     private static final String NOTIFICATION_TAG = "com.android.wifi";
46 
47     private final Context mContext;
48     private NotificationManager mNotificationManager;
49 
WifiNotificationManager(Context context)50     public WifiNotificationManager(Context context) {
51         mContext = context;
52     }
53 
getNotificationManagerForCurrentUser()54     private NotificationManager getNotificationManagerForCurrentUser() {
55         try {
56             return mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
57                     UserHandle.CURRENT).getSystemService(NotificationManager.class);
58         } catch (PackageManager.NameNotFoundException e) {
59             Log.e(TAG, "Failed to get NotificationManager for current user: " + e.getMessage());
60         }
61         return null;
62     }
63 
64     /**
65      * Update to the notification manager fot current user and create notification channels.
66      */
67     // TODO(b/193460475): Remove when tooling supports APIS moving from SystemApi to public
68     @SuppressLint("NewApi")
createNotificationChannels()69     public void createNotificationChannels() {
70         if (mNotificationManager != null) {
71             // Cancel all active notification from Wi-Fi Stack.
72             cleanAllWifiNotification();
73         }
74         mNotificationManager = getNotificationManagerForCurrentUser();
75         if (mNotificationManager == null) {
76             return;
77         }
78         List<NotificationChannel> channelsList = new ArrayList<>();
79         final NotificationChannel networkStatusChannel = new NotificationChannel(
80                 NOTIFICATION_NETWORK_STATUS,
81                 mContext.getResources().getString(
82                         R.string.notification_channel_network_status),
83                 NotificationManager.IMPORTANCE_LOW);
84         channelsList.add(networkStatusChannel);
85 
86         final NotificationChannel networkAlertsChannel = new NotificationChannel(
87                 NOTIFICATION_NETWORK_ALERTS,
88                 mContext.getResources().getString(
89                         R.string.notification_channel_network_alerts),
90                 NotificationManager.IMPORTANCE_HIGH);
91         networkAlertsChannel.setBlockable(true);
92         channelsList.add(networkAlertsChannel);
93 
94         final NotificationChannel networkAvailable = new NotificationChannel(
95                 NOTIFICATION_NETWORK_AVAILABLE,
96                 mContext.getResources().getString(
97                         R.string.notification_channel_network_available),
98                 NotificationManager.IMPORTANCE_LOW);
99         networkAvailable.setBlockable(true);
100         channelsList.add(networkAvailable);
101 
102         final NotificationChannel apmAlertsChannel = new NotificationChannel(
103                 NOTIFICATION_APM_ALERTS,
104                 mContext.getResources().getString(
105                         R.string.notification_channel_apm_alerts),
106                 NotificationManager.IMPORTANCE_HIGH);
107         apmAlertsChannel.setBlockable(true);
108         channelsList.add(apmAlertsChannel);
109 
110         mNotificationManager.createNotificationChannels(channelsList);
111     }
112 
cleanAllWifiNotification()113     private void cleanAllWifiNotification() {
114         for (StatusBarNotification notification : getActiveNotifications()) {
115             if (NOTIFICATION_TAG.equals(notification.getTag())
116                     && notification.getId() != SystemMessage.NOTE_WIFI_APM_NOTIFICATION) {
117                 cancel(notification.getId());
118             }
119         }
120     }
121 
122     /**
123      * Send notification to the current user.
124      */
notify(int id, Notification notification)125     public void notify(int id, Notification notification) {
126         if (mNotificationManager == null) {
127             return;
128         }
129         mNotificationManager.notify(NOTIFICATION_TAG, id, notification);
130     }
131 
132     /**
133      * Cancel the notification fot current user.
134      */
cancel(int id)135     public void cancel(int id) {
136         if (mNotificationManager == null) {
137             return;
138         }
139         mNotificationManager.cancel(NOTIFICATION_TAG, id);
140     }
141 
142     /**
143      * Get active notifications for current user.
144      */
getActiveNotifications()145     public StatusBarNotification[] getActiveNotifications() {
146         if (mNotificationManager == null) {
147             return new StatusBarNotification[0];
148         }
149         return mNotificationManager.getActiveNotifications();
150     }
151 }
152