1 /* 2 * Copyright (C) 2019 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.settings.notification; 18 19 import android.app.settings.SettingsEnums; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.pm.PackageItemInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ServiceInfo; 25 import android.graphics.drawable.Drawable; 26 import android.provider.Settings; 27 import android.service.notification.NotificationAssistantService; 28 import android.text.TextUtils; 29 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.settings.R; 32 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; 33 import com.android.settings.search.BaseSearchIndexProvider; 34 import com.android.settingslib.applications.DefaultAppInfo; 35 import com.android.settingslib.applications.ServiceListing; 36 import com.android.settingslib.widget.CandidateInfo; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 41 public class NotificationAssistantPicker extends DefaultAppPickerFragment implements 42 ServiceListing.Callback { 43 44 private static final String TAG = "NotiAssistantPicker"; 45 46 @VisibleForTesting 47 protected NotificationBackend mNotificationBackend; 48 private List<CandidateInfo> mCandidateInfos = new ArrayList<>(); 49 @VisibleForTesting 50 protected Context mContext; 51 private ServiceListing mServiceListing; 52 53 @Override onAttach(Context context)54 public void onAttach(Context context) { 55 super.onAttach(context); 56 mContext = context; 57 mNotificationBackend = new NotificationBackend(); 58 mServiceListing = new ServiceListing.Builder(context) 59 .setTag(TAG) 60 .setSetting(Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT) 61 .setIntentAction(NotificationAssistantService.SERVICE_INTERFACE) 62 .setPermission(android.Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE) 63 .setNoun("notification assistant") 64 .build(); 65 mServiceListing.addCallback(this); 66 mServiceListing.reload(); 67 } 68 69 @Override onDetach()70 public void onDetach() { 71 super.onDetach(); 72 mServiceListing.removeCallback(this); 73 } 74 75 @Override getPreferenceScreenResId()76 protected int getPreferenceScreenResId() { 77 return R.xml.notification_assistant_settings; 78 } 79 80 @Override getCandidates()81 protected List<? extends CandidateInfo> getCandidates() { 82 return mCandidateInfos; 83 } 84 85 @Override getDefaultKey()86 protected String getDefaultKey() { 87 ComponentName cn = mNotificationBackend.getAllowedNotificationAssistant(); 88 return (cn != null) ? cn.flattenToString() : ""; 89 } 90 91 @Override setDefaultKey(String key)92 protected boolean setDefaultKey(String key) { 93 return mNotificationBackend.setNotificationAssistantGranted( 94 ComponentName.unflattenFromString(key)); 95 } 96 97 @Override getMetricsCategory()98 public int getMetricsCategory() { 99 return SettingsEnums.DEFAULT_NOTIFICATION_ASSISTANT; 100 } 101 102 @Override getConfirmationMessage(CandidateInfo info)103 protected CharSequence getConfirmationMessage(CandidateInfo info) { 104 if (TextUtils.isEmpty(info.getKey())) { 105 return null; 106 } 107 return mContext.getString(R.string.notification_assistant_security_warning_summary, 108 info.loadLabel()); 109 } 110 111 @Override onServicesReloaded(List<ServiceInfo> services)112 public void onServicesReloaded(List<ServiceInfo> services) { 113 List<CandidateInfo> list = new ArrayList<>(); 114 services.sort(new PackageItemInfo.DisplayNameComparator(mPm)); 115 for (ServiceInfo service : services) { 116 if (mContext.getPackageManager().checkPermission( 117 android.Manifest.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE, 118 service.packageName) == PackageManager.PERMISSION_GRANTED) { 119 final ComponentName cn = new ComponentName(service.packageName, service.name); 120 list.add(new DefaultAppInfo(mContext, mPm, mUserId, cn)); 121 } 122 } 123 list.add(new CandidateNone(mContext)); 124 mCandidateInfos = list; 125 } 126 127 public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 128 new BaseSearchIndexProvider(R.xml.notification_assistant_settings); 129 130 public static class CandidateNone extends CandidateInfo { 131 132 public Context mContext; 133 CandidateNone(Context context)134 public CandidateNone(Context context) { 135 super(true); 136 mContext = context; 137 } 138 139 @Override loadLabel()140 public CharSequence loadLabel() { 141 return mContext.getString(R.string.no_notification_assistant); 142 } 143 144 @Override loadIcon()145 public Drawable loadIcon() { 146 return null; 147 } 148 149 @Override getKey()150 public String getKey() { 151 return ""; 152 } 153 } 154 } 155