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.systemApp, mAppRow.appImportance, mAppRow.banned); 94 setupPriorityPref(mAppRow.appBypassDnd); 95 setupVisOverridePref(mAppRow.appVisOverride); 96 updateDependents(mAppRow.appImportance); 97 } 98 } 99 100 @Override 101 protected void updateDependents(int importance) { 102 LockPatternUtils utils = new LockPatternUtils(getActivity()); 103 boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId()); 104 UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId()); 105 if (parentUser != null){ 106 lockscreenSecure |= utils.isSecure(parentUser.id); 107 } 108 109 if (getPreferenceScreen().findPreference(mBlock.getKey()) != null) { 110 setVisible(mSilent, checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance)); 111 mSilent.setChecked(importance == Ranking.IMPORTANCE_LOW); 112 } 113 setVisible(mPriority, checkCanBeVisible(Ranking.IMPORTANCE_DEFAULT, importance) 114 || (checkCanBeVisible(Ranking.IMPORTANCE_LOW, importance) 115 && mDndVisualEffectsSuppressed)); 116 setVisible(mVisibilityOverride, 117 checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance) && lockscreenSecure); 118 } 119 120 protected boolean checkCanBeVisible(int minImportanceVisible, int importance) { 121 if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { 122 return true; 123 } 124 return importance >= minImportanceVisible; 125 } 126 127 private List<ResolveInfo> queryNotificationConfigActivities() { 128 if (DEBUG) Log.d(TAG, "APP_NOTIFICATION_PREFS_CATEGORY_INTENT is " 129 + APP_NOTIFICATION_PREFS_CATEGORY_INTENT); 130 final List<ResolveInfo> resolveInfos = mPm.queryIntentActivities( 131 APP_NOTIFICATION_PREFS_CATEGORY_INTENT, 132 0 //PackageManager.MATCH_DEFAULT_ONLY 133 ); 134 return resolveInfos; 135 } 136 137 private void collectConfigActivities(ArrayMap<String, AppRow> rows) { 138 final List<ResolveInfo> resolveInfos = queryNotificationConfigActivities(); 139 applyConfigActivities(rows, resolveInfos); 140 } 141 142 private void applyConfigActivities(ArrayMap<String, AppRow> rows, 143 List<ResolveInfo> resolveInfos) { 144 if (DEBUG) Log.d(TAG, "Found " + resolveInfos.size() + " preference activities" 145 + (resolveInfos.size() == 0 ? " ;_;" : "")); 146 for (ResolveInfo ri : resolveInfos) { 147 final ActivityInfo activityInfo = ri.activityInfo; 148 final ApplicationInfo appInfo = activityInfo.applicationInfo; 149 final AppRow row = rows.get(appInfo.packageName); 150 if (row == null) { 151 if (DEBUG) Log.v(TAG, "Ignoring notification preference activity (" 152 + activityInfo.name + ") for unknown package " 153 + activityInfo.packageName); 154 continue; 155 } 156 if (row.settingsIntent != null) { 157 if (DEBUG) Log.v(TAG, "Ignoring duplicate notification preference activity (" 158 + activityInfo.name + ") for package " 159 + activityInfo.packageName); 160 continue; 161 } 162 row.settingsIntent = new Intent(APP_NOTIFICATION_PREFS_CATEGORY_INTENT) 163 .setClassName(activityInfo.packageName, activityInfo.name); 164 } 165 } 166 } 167