1 /* 2 * Copyright (C) 2016 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.utils; 17 18 import android.app.ActivityManager; 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.ActivityInfo; 24 import android.content.pm.ComponentInfo; 25 import android.content.pm.PackageManager; 26 import android.content.pm.ResolveInfo; 27 import android.content.pm.ServiceInfo; 28 import android.util.ArraySet; 29 import android.util.Slog; 30 31 import androidx.annotation.Nullable; 32 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.Set; 36 37 public class ZenServiceListing { 38 private static final String TAG = "ZenServiceListing"; 39 40 private final Context mContext; 41 private final ManagedServiceSettings.Config mConfig; 42 private final Set<ComponentInfo> mApprovedComponents = new ArraySet<>(); 43 private final List<Callback> mZenCallbacks = new ArrayList<>(); 44 private final NotificationManager mNm; 45 46 // only used when android.app.modes_ui flag is true 47 @Nullable 48 private String mPkg = null; 49 ZenServiceListing(Context context, ManagedServiceSettings.Config config)50 public ZenServiceListing(Context context, ManagedServiceSettings.Config config) { 51 this(context, config, null); 52 } 53 ZenServiceListing(Context context, ManagedServiceSettings.Config config, @Nullable String pkg)54 public ZenServiceListing(Context context, ManagedServiceSettings.Config config, @Nullable String pkg) { 55 mContext = context; 56 mConfig = config; 57 mPkg = pkg; 58 mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 59 } 60 findService(final ComponentName cn)61 public ComponentInfo findService(final ComponentName cn) { 62 if (cn == null) { 63 return null; 64 } 65 for (ComponentInfo component : mApprovedComponents) { 66 final ComponentName ci = new ComponentName(component.packageName, component.name); 67 if (ci.equals(cn)) { 68 return component; 69 } 70 } 71 return null; 72 } 73 addZenCallback(Callback callback)74 public void addZenCallback(Callback callback) { 75 mZenCallbacks.add(callback); 76 } 77 removeZenCallback(Callback callback)78 public void removeZenCallback(Callback callback) { 79 mZenCallbacks.remove(callback); 80 } 81 reloadApprovedServices()82 public void reloadApprovedServices() { 83 mApprovedComponents.clear(); 84 85 List<String> enabledNotificationListenerPkgs = mNm.getEnabledNotificationListenerPackages(); 86 List<ComponentInfo> components = new ArrayList<>(); 87 getServices(mConfig, components, mContext.getPackageManager()); 88 getActivities(mConfig, components, mContext.getPackageManager()); 89 for (ComponentInfo componentInfo : components) { 90 final String pkg = componentInfo.getComponentName().getPackageName(); 91 if (mNm.isNotificationPolicyAccessGrantedForPackage(pkg) 92 || enabledNotificationListenerPkgs.contains(pkg)) { 93 mApprovedComponents.add(componentInfo); 94 } 95 } 96 97 if (!mApprovedComponents.isEmpty()) { 98 for (Callback callback : mZenCallbacks) { 99 callback.onComponentsReloaded(mApprovedComponents); 100 } 101 } 102 } 103 getServices(ManagedServiceSettings.Config c, List<ComponentInfo> list, PackageManager pm)104 private void getServices(ManagedServiceSettings.Config c, List<ComponentInfo> list, 105 PackageManager pm) { 106 final int user = ActivityManager.getCurrentUser(); 107 108 Intent queryIntent = new Intent(c.intentAction); 109 if (mPkg != null) { 110 queryIntent.setPackage(mPkg); 111 } 112 List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser( 113 queryIntent, 114 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, 115 user); 116 117 for (int i = 0, count = installedServices.size(); i < count; i++) { 118 ResolveInfo resolveInfo = installedServices.get(i); 119 ServiceInfo info = resolveInfo.serviceInfo; 120 121 if (!c.permission.equals(info.permission)) { 122 Slog.w(c.tag, "Skipping " + c.noun + " service " 123 + info.packageName + "/" + info.name 124 + ": it does not require the permission " 125 + c.permission); 126 continue; 127 } 128 if (list != null) { 129 list.add(info); 130 } 131 } 132 } 133 getActivities(ManagedServiceSettings.Config c, List<ComponentInfo> list, PackageManager pm)134 private void getActivities(ManagedServiceSettings.Config c, List<ComponentInfo> list, 135 PackageManager pm) { 136 final int user = ActivityManager.getCurrentUser(); 137 138 Intent queryIntent = new Intent(c.configIntentAction); 139 if (mPkg != null) { 140 queryIntent.setPackage(mPkg); 141 } 142 List<ResolveInfo> resolveInfos = pm.queryIntentActivitiesAsUser( 143 queryIntent, 144 PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA, 145 user); 146 147 for (int i = 0, count = resolveInfos.size(); i < count; i++) { 148 ResolveInfo resolveInfo = resolveInfos.get(i); 149 ActivityInfo info = resolveInfo.activityInfo; 150 if (list != null) { 151 list.add(info); 152 } 153 } 154 } 155 156 public interface Callback { onComponentsReloaded(Set<ComponentInfo> components)157 void onComponentsReloaded(Set<ComponentInfo> components); 158 } 159 } 160