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 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 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 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 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 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 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 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 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 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 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 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 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 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