1 /* 2 * Copyright (C) 2014 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.Notification; 20 import android.app.NotificationManager; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.content.pm.ApplicationInfo; 24 import android.content.pm.ResolveInfo; 25 import android.content.pm.UserInfo; 26 import android.os.Bundle; 27 import android.os.UserHandle; 28 import android.service.notification.NotificationListenerService.Ranking; 29 import android.util.ArrayMap; 30 import android.util.Log; 31 32 import com.android.internal.logging.MetricsProto.MetricsEvent; 33 import com.android.internal.widget.LockPatternUtils; 34 import com.android.settings.AppHeader; 35 import com.android.settings.R; 36 import com.android.settings.notification.NotificationBackend.AppRow; 37 import com.android.settingslib.RestrictedSwitchPreference; 38 39 40 import java.util.List; 41 42 /** These settings are per app, so should not be returned in global search results. */ 43 public class AppNotificationSettings extends NotificationSettingsBase { 44 private static final String TAG = "AppNotificationSettings"; 45 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 46 47 private static final Intent APP_NOTIFICATION_PREFS_CATEGORY_INTENT 48 = new Intent(Intent.ACTION_MAIN) 49 .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES); 50 51 private AppRow mAppRow; 52 private boolean mDndVisualEffectsSuppressed; 53 54 @Override 55 public void onActivityCreated(Bundle savedInstanceState) { 56 super.onActivityCreated(savedInstanceState); 57 if (mAppRow == null) return; 58 AppHeader.createAppHeader(this, mAppRow.icon, mAppRow.label, mAppRow.pkg, mAppRow.uid, 59 mAppRow.settingsIntent); 60 } 61 62 @Override 63 protected int getMetricsCategory() { 64 return MetricsEvent.NOTIFICATION_APP_NOTIFICATION; 65 } 66 67 @Override 68 public void onCreate(Bundle savedInstanceState) { 69 super.onCreate(savedInstanceState); 70 71 addPreferencesFromResource(R.xml.app_notification_settings); 72 mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); 73 mPriority = 74 (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND); 75 mVisibilityOverride = 76 (RestrictedDropDownPreference) getPreferenceScreen().findPreference( 77 KEY_VISIBILITY_OVERRIDE); 78 mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK); 79 mSilent = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_SILENT); 80 81 if (mPkgInfo != null) { 82 mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo); 83 84 NotificationManager.Policy policy = 85 NotificationManager.from(mContext).getNotificationPolicy(); 86 mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0; 87 88 // load settings intent 89 ArrayMap<String, AppRow> rows = new ArrayMap<String, AppRow>(); 90 rows.put(mAppRow.pkg, mAppRow); 91 collectConfigActivities(rows); 92 93 setupImportancePrefs(mAppRow.cantBlock, mAppRow.cantSilence, 94 mAppRow.appImportance, mAppRow.banned); 95 setupPriorityPref(mAppRow.appBypassDnd); 96 setupVisOverridePref(mAppRow.appVisOverride); 97 updateDependents(mAppRow.appImportance); 98 } 99 } 100 101 @Override 102 protected void updateDependents(int importance) { 103 LockPatternUtils utils = new LockPatternUtils(getActivity()); 104 boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId()); 105 UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId()); 106 if (parentUser != null){ 107 lockscreenSecure |= utils.isSecure(parentUser.id); 108 } 109 110 if (getPreferenceScreen().findPreference(mBlock.getKey()) != null) { 111 setVisible(mSilent, checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance)); 112 mSilent.setChecked(importance == Ranking.IMPORTANCE_LOW); 113 } 114 setVisible(mPriority, checkCanBeVisible(Ranking.IMPORTANCE_DEFAULT, importance) 115 || (checkCanBeVisible(Ranking.IMPORTANCE_LOW, importance) 116 && mDndVisualEffectsSuppressed)); 117 setVisible(mVisibilityOverride, 118 checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance) && lockscreenSecure); 119 } 120 121 protected boolean checkCanBeVisible(int minImportanceVisible, int importance) { 122 if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { 123 return true; 124 } 125 return importance >= minImportanceVisible; 126 } 127 128 private List<ResolveInfo> queryNotificationConfigActivities() { 129 if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " 130 + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); 131 final List<ResolveInfo> resolveInfos = mPm.queryIntentActivities( 132 APP_NOTIFICATION_PREFS_CATEGORY_INTENT, 133 0 //PackageManager.MATCH_DEFAULT_ONLY 134 ); 135 return resolveInfos; 136 } 137 138 private void collectConfigActivities(ArrayMap<String, AppRow> rows) { 139 final List<ResolveInfo> resolveInfos = queryNotificationConfigActivities(); 140 applyConfigActivities(rows, resolveInfos); 141 } 142 143 private void applyConfigActivities(ArrayMap<String, AppRow> rows, 144 List<ResolveInfo> resolveInfos) { 145 if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities" 146 + (resolveInfos.size() == 0 ? " ;_;" : "")); 147 for (ResolveInfo ri : resolveInfos) { 148 final ActivityInfo activityInfo = ri.activityInfo; 149 final ApplicationInfo appInfo = activityInfo.applicationInfo; 150 final AppRow row = rows.get(appInfo.packageName); 151 if (row == null) { 152 if (DEBUG) Log.v(TAG, "Ignoring notification preference activity (" 153 + activityInfo.name + ") for unknown package " 154 + activityInfo.packageName); 155 continue; 156 } 157 if (row.settingsIntent != null) { 158 if (DEBUG) Log.v(TAG, "Ignoring duplicate notification preference activity (" 159 + activityInfo.name + ") for package " 160 + activityInfo.packageName); 161 continue; 162 } 163 row.settingsIntent = new Intent(APP_NOTIFICATION_PREFS_CATEGORY_INTENT) 164 .setClassName(activityInfo.packageName, activityInfo.name); 165 } 166 } 167 } 168