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.applications.LayoutPreference; 37 import com.android.settings.notification.NotificationBackend.AppRow; 38 import com.android.settingslib.RestrictedSwitchPreference; 39 import com.android.settingslib.RestrictedPreference; 40 41 42 import java.util.List; 43 44 /** These settings are per app, so should not be returned in global search results. */ 45 public class AppNotificationSettings extends NotificationSettingsBase { 46 private static final String TAG = "AppNotificationSettings"; 47 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 48 49 private static final Intent APP_NOTIFICATION_PREFS_CATEGORY_INTENT 50 = new Intent(Intent.ACTION_MAIN) 51 .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES); 52 53 private AppRow mAppRow; 54 private boolean mDndVisualEffectsSuppressed; 55 56 @Override onActivityCreated(Bundle savedInstanceState)57 public void onActivityCreated(Bundle savedInstanceState) { 58 super.onActivityCreated(savedInstanceState); 59 if (mAppRow == null) return; 60 AppHeader.createAppHeader(this, mAppRow.icon, mAppRow.label, mAppRow.pkg, mAppRow.uid, 61 mAppRow.settingsIntent); 62 } 63 64 @Override getMetricsCategory()65 protected int getMetricsCategory() { 66 return MetricsEvent.NOTIFICATION_APP_NOTIFICATION; 67 } 68 69 @Override onCreate(Bundle savedInstanceState)70 public void onCreate(Bundle savedInstanceState) { 71 super.onCreate(savedInstanceState); 72 73 addPreferencesFromResource(R.xml.app_notification_settings); 74 mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); 75 mPriority = 76 (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND); 77 mVisibilityOverride = 78 (RestrictedDropDownPreference) getPreferenceScreen().findPreference( 79 KEY_VISIBILITY_OVERRIDE); 80 mBlock = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BLOCK); 81 mSilent = (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_SILENT); 82 83 if (mPkgInfo != null) { 84 mAppRow = mBackend.loadAppRow(mContext, mPm, mPkgInfo); 85 86 NotificationManager.Policy policy = 87 NotificationManager.from(mContext).getNotificationPolicy(); 88 mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0; 89 90 // load settings intent 91 ArrayMap<String, AppRow> rows = new ArrayMap<String, AppRow>(); 92 rows.put(mAppRow.pkg, mAppRow); 93 collectConfigActivities(rows); 94 95 setupImportancePrefs(mAppRow.systemApp, mAppRow.appImportance, mAppRow.banned); 96 setupPriorityPref(mAppRow.appBypassDnd); 97 setupVisOverridePref(mAppRow.appVisOverride); 98 updateDependents(mAppRow.appImportance); 99 } 100 } 101 102 @Override updateDependents(int importance)103 protected void updateDependents(int importance) { 104 LockPatternUtils utils = new LockPatternUtils(getActivity()); 105 boolean lockscreenSecure = utils.isSecure(UserHandle.myUserId()); 106 UserInfo parentUser = mUm.getProfileParent(UserHandle.myUserId()); 107 if (parentUser != null){ 108 lockscreenSecure |= utils.isSecure(parentUser.id); 109 } 110 111 if (getPreferenceScreen().findPreference(mBlock.getKey()) != null) { 112 setVisible(mSilent, checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance)); 113 mSilent.setChecked(importance == Ranking.IMPORTANCE_LOW); 114 } 115 setVisible(mPriority, checkCanBeVisible(Ranking.IMPORTANCE_DEFAULT, importance) 116 && !mDndVisualEffectsSuppressed); 117 setVisible(mVisibilityOverride, 118 checkCanBeVisible(Ranking.IMPORTANCE_MIN, importance) && lockscreenSecure); 119 } 120 checkCanBeVisible(int minImportanceVisible, int importance)121 protected boolean checkCanBeVisible(int minImportanceVisible, int importance) { 122 if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { 123 return true; 124 } 125 return importance >= minImportanceVisible; 126 } 127 queryNotificationConfigActivities()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 collectConfigActivities(ArrayMap<String, AppRow> rows)138 private void collectConfigActivities(ArrayMap<String, AppRow> rows) { 139 final List<ResolveInfo> resolveInfos = queryNotificationConfigActivities(); 140 applyConfigActivities(rows, resolveInfos); 141 } 142 applyConfigActivities(ArrayMap<String, AppRow> rows, List<ResolveInfo> resolveInfos)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