• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.permissioncontroller.role.utils;
18 
19 import android.app.NotificationManager;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.content.pm.ServiceInfo;
26 import android.service.notification.NotificationListenerService;
27 import android.util.Log;
28 
29 import androidx.annotation.NonNull;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Objects;
34 
35 /**
36  * Utility methods about Notification permissions.
37  */
38 public final class NotificationUtils {
39 
40     public static final String LOG_TAG = NotificationUtils.class.getSimpleName();
41 
NotificationUtils()42     private NotificationUtils() {}
43 
44     /**
45      * Grants the NotificationListener access.
46      *
47      * @param context     the {@code Context} to retrieve system services
48      * @param packageName the package name implements the NotificationListener
49      */
grantNotificationAccessForPackage(@onNull Context context, @NonNull String packageName)50     public static void grantNotificationAccessForPackage(@NonNull Context context,
51             @NonNull String packageName) {
52         setNotificationGrantStateForPackage(context, packageName, true);
53     }
54 
55     /**
56      * Revokes the NotificationListener access.
57      *
58      * @param context     the {@code Context} to retrieve system services
59      * @param packageName the package name implements the NotificationListener
60      */
revokeNotificationAccessForPackage(@onNull Context context, @NonNull String packageName)61     public static void revokeNotificationAccessForPackage(@NonNull Context context,
62             @NonNull String packageName) {
63         setNotificationGrantStateForPackage(context, packageName, false);
64     }
65 
66 
setNotificationGrantStateForPackage(@onNull Context context, @NonNull String packageName, boolean granted)67     private static void setNotificationGrantStateForPackage(@NonNull Context context,
68             @NonNull String packageName, boolean granted) {
69         List<ComponentName> notificationListenersForPackage =
70                 getNotificationListenersForPackage(packageName, context);
71         NotificationManager notificationManager =
72                 context.getSystemService(NotificationManager.class);
73         for (ComponentName componentName : notificationListenersForPackage) {
74             notificationManager.setNotificationListenerAccessGranted(
75                     componentName, granted, false);
76         }
77     }
78 
getNotificationListenersForPackage( @onNull String packageName, @NonNull Context context)79     private static List<ComponentName> getNotificationListenersForPackage(
80             @NonNull String packageName, @NonNull Context context) {
81         List<ResolveInfo> allListeners = context.getPackageManager().queryIntentServices(
82                 new Intent(NotificationListenerService.SERVICE_INTERFACE).setPackage(packageName),
83                 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
84         ArrayList<ComponentName> pkgListeners = new ArrayList<>();
85         for (ResolveInfo service : allListeners) {
86             ServiceInfo serviceInfo = service.serviceInfo;
87             if (Objects.equals(serviceInfo.permission,
88                     android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE)
89                     && packageName.equals(serviceInfo.packageName)) {
90                 pkgListeners.add(new ComponentName(serviceInfo.packageName, serviceInfo.name));
91             }
92         }
93         Log.d(LOG_TAG, "getNotificationListenersForPackage(" + packageName + "): " + pkgListeners);
94         return pkgListeners;
95     }
96 
97 }
98