1 /*
2  * Copyright (C) 2015 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 package com.android.settings.notification;
17 
18 import android.app.INotificationManager;
19 import android.app.NotificationChannel;
20 import android.app.NotificationChannelGroup;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.ApplicationInfo;
24 import android.content.pm.PackageInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ParceledListSlice;
27 import android.graphics.drawable.Drawable;
28 import android.os.ServiceManager;
29 import android.os.UserHandle;
30 import android.util.IconDrawableFactory;
31 import android.util.Log;
32 
33 import com.android.internal.annotations.VisibleForTesting;
34 import com.android.settingslib.Utils;
35 
36 public class NotificationBackend {
37     private static final String TAG = "NotificationBackend";
38 
39     static INotificationManager sINM = INotificationManager.Stub.asInterface(
40             ServiceManager.getService(Context.NOTIFICATION_SERVICE));
41 
loadAppRow(Context context, PackageManager pm, ApplicationInfo app)42     public AppRow loadAppRow(Context context, PackageManager pm, ApplicationInfo app) {
43         final AppRow row = new AppRow();
44         row.pkg = app.packageName;
45         row.uid = app.uid;
46         try {
47             row.label = app.loadLabel(pm);
48         } catch (Throwable t) {
49             Log.e(TAG, "Error loading application label for " + row.pkg, t);
50             row.label = row.pkg;
51         }
52         row.icon = IconDrawableFactory.newInstance(context).getBadgedIcon(app);
53         row.banned = getNotificationsBanned(row.pkg, row.uid);
54         row.showBadge = canShowBadge(row.pkg, row.uid);
55         row.userId = UserHandle.getUserId(row.uid);
56         return row;
57     }
58 
loadAppRow(Context context, PackageManager pm, PackageInfo app)59     public AppRow loadAppRow(Context context, PackageManager pm, PackageInfo app) {
60         final AppRow row = loadAppRow(context, pm, app.applicationInfo);
61         row.systemApp = Utils.isSystemPackage(context.getResources(), pm, app);
62         final String[] nonBlockablePkgs = context.getResources().getStringArray(
63                     com.android.internal.R.array.config_nonBlockableNotificationPackages);
64         markAppRowWithBlockables(nonBlockablePkgs, row, app.packageName);
65         return row;
66     }
67 
markAppRowWithBlockables(String[] nonBlockablePkgs, AppRow row, String packageName)68     @VisibleForTesting static void markAppRowWithBlockables(String[] nonBlockablePkgs, AppRow row,
69             String packageName) {
70         if (nonBlockablePkgs != null) {
71             int N = nonBlockablePkgs.length;
72             for (int i = 0; i < N; i++) {
73                 String pkg = nonBlockablePkgs[i];
74                 if (pkg == null) {
75                     continue;
76                 } else if (pkg.contains(":")) {
77                     // Interpret as channel; lock only this channel for this app.
78                     if (packageName.equals(pkg.split(":", 2)[0])) {
79                         row.lockedChannelId = pkg.split(":", 2 )[1];
80                     }
81                 } else if (packageName.equals(nonBlockablePkgs[i])) {
82                     row.systemApp = row.lockedImportance = true;
83                 }
84             }
85         }
86     }
87 
getNotificationsBanned(String pkg, int uid)88     public boolean getNotificationsBanned(String pkg, int uid) {
89         try {
90             final boolean enabled = sINM.areNotificationsEnabledForPackage(pkg, uid);
91             return !enabled;
92         } catch (Exception e) {
93             Log.w(TAG, "Error calling NoMan", e);
94             return false;
95         }
96     }
97 
setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled)98     public boolean setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
99         try {
100             sINM.setNotificationsEnabledForPackage(pkg, uid, enabled);
101             return true;
102         } catch (Exception e) {
103             Log.w(TAG, "Error calling NoMan", e);
104             return false;
105         }
106     }
107 
canShowBadge(String pkg, int uid)108     public boolean canShowBadge(String pkg, int uid) {
109         try {
110             return sINM.canShowBadge(pkg, uid);
111         } catch (Exception e) {
112             Log.w(TAG, "Error calling NoMan", e);
113             return false;
114         }
115     }
116 
setShowBadge(String pkg, int uid, boolean showBadge)117     public boolean setShowBadge(String pkg, int uid, boolean showBadge) {
118         try {
119             sINM.setShowBadge(pkg, uid, showBadge);
120             return true;
121         } catch (Exception e) {
122             Log.w(TAG, "Error calling NoMan", e);
123             return false;
124         }
125     }
126 
getChannel(String pkg, int uid, String channelId)127     public NotificationChannel getChannel(String pkg, int uid, String channelId) {
128         if (channelId == null) {
129             return null;
130         }
131         try {
132             return sINM.getNotificationChannelForPackage(pkg, uid, channelId, true);
133         } catch (Exception e) {
134             Log.w(TAG, "Error calling NoMan", e);
135             return null;
136         }
137     }
138 
139 
getGroup(String groupId, String pkg, int uid)140     public NotificationChannelGroup getGroup(String groupId, String pkg, int uid) {
141         if (groupId == null) {
142             return null;
143         }
144         try {
145             return sINM.getNotificationChannelGroupForPackage(groupId, pkg, uid);
146         } catch (Exception e) {
147             Log.w(TAG, "Error calling NoMan", e);
148             return null;
149         }
150     }
151 
getChannelGroups(String pkg, int uid)152     public ParceledListSlice<NotificationChannelGroup> getChannelGroups(String pkg, int uid) {
153         try {
154             return sINM.getNotificationChannelGroupsForPackage(pkg, uid, false);
155         } catch (Exception e) {
156             Log.w(TAG, "Error calling NoMan", e);
157             return ParceledListSlice.emptyList();
158         }
159     }
160 
updateChannel(String pkg, int uid, NotificationChannel channel)161     public void updateChannel(String pkg, int uid, NotificationChannel channel) {
162         try {
163             sINM.updateNotificationChannelForPackage(pkg, uid, channel);
164         } catch (Exception e) {
165             Log.w(TAG, "Error calling NoMan", e);
166         }
167     }
168 
getDeletedChannelCount(String pkg, int uid)169     public int getDeletedChannelCount(String pkg, int uid) {
170         try {
171             return sINM.getDeletedChannelCount(pkg, uid);
172         } catch (Exception e) {
173             Log.w(TAG, "Error calling NoMan", e);
174             return 0;
175         }
176     }
177 
onlyHasDefaultChannel(String pkg, int uid)178     public boolean onlyHasDefaultChannel(String pkg, int uid) {
179         try {
180             return sINM.onlyHasDefaultChannel(pkg, uid);
181         } catch (Exception e) {
182             Log.w(TAG, "Error calling NoMan", e);
183             return false;
184         }
185     }
186 
187     static class Row {
188         public String section;
189     }
190 
191     public static class AppRow extends Row {
192         public String pkg;
193         public int uid;
194         public Drawable icon;
195         public CharSequence label;
196         public Intent settingsIntent;
197         public boolean banned;
198         public boolean first;  // first app in section
199         public boolean systemApp;
200         public boolean lockedImportance;
201         public String lockedChannelId;
202         public boolean showBadge;
203         public int userId;
204     }
205 }
206