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.ContentResolver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.pm.PackageManager; 25 import android.content.pm.ResolveInfo; 26 import android.content.pm.ServiceInfo; 27 import android.provider.Settings; 28 import android.text.TextUtils; 29 import android.util.ArraySet; 30 import android.util.Slog; 31 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.List; 35 import java.util.Set; 36 37 public class ZenServiceListing { 38 39 private final Context mContext; 40 private final ManagedServiceSettings.Config mConfig; 41 private final Set<ServiceInfo> mApprovedServices = new ArraySet<ServiceInfo>(); 42 private final List<Callback> mZenCallbacks = new ArrayList<>(); 43 private final NotificationManager mNm; 44 45 public ZenServiceListing(Context context, ManagedServiceSettings.Config config) { 46 mContext = context; 47 mConfig = config; 48 mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 49 } 50 51 public ServiceInfo findService(final ComponentName cn) { 52 for (ServiceInfo service : mApprovedServices) { 53 final ComponentName serviceCN = new ComponentName(service.packageName, service.name); 54 if (serviceCN.equals(cn)) { 55 return service; 56 } 57 } 58 return null; 59 } 60 61 public void addZenCallback(Callback callback) { 62 mZenCallbacks.add(callback); 63 } 64 65 public void removeZenCallback(Callback callback) { 66 mZenCallbacks.remove(callback); 67 } 68 69 public void reloadApprovedServices() { 70 mApprovedServices.clear(); 71 72 List<String> enabledNotificationListenerPkgs = mNm.getEnabledNotificationListenerPackages(); 73 List<ServiceInfo> services = new ArrayList<>(); 74 getServices(mConfig, services, mContext.getPackageManager()); 75 for (ServiceInfo service : services) { 76 final String servicePackage = service.getComponentName().getPackageName(); 77 if (mNm.isNotificationPolicyAccessGrantedForPackage(servicePackage) 78 || enabledNotificationListenerPkgs.contains(servicePackage)) { 79 mApprovedServices.add(service); 80 } 81 } 82 83 if (!mApprovedServices.isEmpty()) { 84 for (Callback callback : mZenCallbacks) { 85 callback.onServicesReloaded(mApprovedServices); 86 } 87 } 88 } 89 90 private static int getServices(ManagedServiceSettings.Config c, List<ServiceInfo> list, 91 PackageManager pm) { 92 int services = 0; 93 if (list != null) { 94 list.clear(); 95 } 96 final int user = ActivityManager.getCurrentUser(); 97 98 List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser( 99 new Intent(c.intentAction), 100 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA, 101 user); 102 103 for (int i = 0, count = installedServices.size(); i < count; i++) { 104 ResolveInfo resolveInfo = installedServices.get(i); 105 ServiceInfo info = resolveInfo.serviceInfo; 106 107 if (!c.permission.equals(info.permission)) { 108 Slog.w(c.tag, "Skipping " + c.noun + " service " 109 + info.packageName + "/" + info.name 110 + ": it does not require the permission " 111 + c.permission); 112 continue; 113 } 114 if (list != null) { 115 list.add(info); 116 } 117 services++; 118 } 119 return services; 120 } 121 122 public interface Callback { 123 void onServicesReloaded(Set<ServiceInfo> services); 124 } 125 } 126