Home | History | Annotate | Download | only in notification
      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