1 /* 2 * Copyright (C) 2017 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 static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; 20 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; 21 22 import android.app.ActivityManager; 23 import android.app.AutomaticZenRule; 24 import android.app.NotificationManager; 25 import android.content.Context; 26 import android.net.Uri; 27 import android.provider.Settings; 28 import android.service.notification.ZenModeConfig; 29 import android.support.annotation.VisibleForTesting; 30 import android.util.Log; 31 32 import com.android.settings.R; 33 34 public class ZenModeBackend { 35 @VisibleForTesting 36 protected static final String ZEN_MODE_FROM_ANYONE = "zen_mode_from_anyone"; 37 @VisibleForTesting 38 protected static final String ZEN_MODE_FROM_CONTACTS = "zen_mode_from_contacts"; 39 @VisibleForTesting 40 protected static final String ZEN_MODE_FROM_STARRED = "zen_mode_from_starred"; 41 @VisibleForTesting 42 protected static final String ZEN_MODE_FROM_NONE = "zen_mode_from_none"; 43 protected static final int SOURCE_NONE = -1; 44 45 private static ZenModeBackend sInstance; 46 47 protected int mZenMode; 48 /** gets policy last set by updatePolicy **/ 49 protected NotificationManager.Policy mPolicy; 50 private final NotificationManager mNotificationManager; 51 52 private String TAG = "ZenModeSettingsBackend"; 53 private final Context mContext; 54 getInstance(Context context)55 public static ZenModeBackend getInstance(Context context) { 56 if (sInstance == null) { 57 sInstance = new ZenModeBackend(context); 58 } 59 return sInstance; 60 } 61 ZenModeBackend(Context context)62 public ZenModeBackend(Context context) { 63 mContext = context; 64 mNotificationManager = (NotificationManager) context.getSystemService( 65 Context.NOTIFICATION_SERVICE); 66 updateZenMode(); 67 updatePolicy(); 68 } 69 updatePolicy()70 protected void updatePolicy() { 71 if (mNotificationManager != null) { 72 mPolicy = mNotificationManager.getNotificationPolicy(); 73 } 74 } 75 updateZenMode()76 protected void updateZenMode() { 77 mZenMode = Settings.Global.getInt(mContext.getContentResolver(), 78 Settings.Global.ZEN_MODE, mZenMode); 79 } 80 setZenRule(String id, AutomaticZenRule rule)81 protected boolean setZenRule(String id, AutomaticZenRule rule) { 82 return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule); 83 } 84 setZenMode(int zenMode)85 protected void setZenMode(int zenMode) { 86 NotificationManager.from(mContext).setZenMode(zenMode, null, TAG); 87 mZenMode = getZenMode(); 88 } 89 setZenModeForDuration(int minutes)90 protected void setZenModeForDuration(int minutes) { 91 Uri conditionId = ZenModeConfig.toTimeCondition(mContext, minutes, 92 ActivityManager.getCurrentUser(), true).id; 93 mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, 94 conditionId, TAG); 95 mZenMode = getZenMode(); 96 } 97 getZenMode()98 protected int getZenMode() { 99 mZenMode = Settings.Global.getInt(mContext.getContentResolver(), 100 Settings.Global.ZEN_MODE, mZenMode); 101 return mZenMode; 102 } 103 isVisualEffectSuppressed(int visualEffect)104 protected boolean isVisualEffectSuppressed(int visualEffect) { 105 return (mPolicy.suppressedVisualEffects & visualEffect) != 0; 106 } 107 isPriorityCategoryEnabled(int categoryType)108 protected boolean isPriorityCategoryEnabled(int categoryType) { 109 return (mPolicy.priorityCategories & categoryType) != 0; 110 } 111 getNewPriorityCategories(boolean allow, int categoryType)112 protected int getNewPriorityCategories(boolean allow, int categoryType) { 113 int priorityCategories = mPolicy.priorityCategories; 114 if (allow) { 115 priorityCategories |= categoryType; 116 } else { 117 priorityCategories &= ~categoryType; 118 } 119 return priorityCategories; 120 } 121 getPriorityCallSenders()122 protected int getPriorityCallSenders() { 123 if (isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS)) { 124 return mPolicy.priorityCallSenders; 125 } 126 127 return SOURCE_NONE; 128 } 129 getPriorityMessageSenders()130 protected int getPriorityMessageSenders() { 131 if (isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) { 132 return mPolicy.priorityMessageSenders; 133 } 134 return SOURCE_NONE; 135 } 136 saveVisualEffectsPolicy(int category, boolean suppress)137 protected void saveVisualEffectsPolicy(int category, boolean suppress) { 138 Settings.Global.putInt(mContext.getContentResolver(), 139 Settings.Global.ZEN_SETTINGS_UPDATED, 1); 140 141 int suppressedEffects = getNewSuppressedEffects(suppress, category); 142 savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders, 143 mPolicy.priorityMessageSenders, suppressedEffects); 144 } 145 saveSoundPolicy(int category, boolean allow)146 protected void saveSoundPolicy(int category, boolean allow) { 147 int priorityCategories = getNewPriorityCategories(allow, category); 148 savePolicy(priorityCategories, mPolicy.priorityCallSenders, 149 mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects); 150 } 151 savePolicy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)152 protected void savePolicy(int priorityCategories, int priorityCallSenders, 153 int priorityMessageSenders, int suppressedVisualEffects) { 154 mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders, 155 priorityMessageSenders, suppressedVisualEffects); 156 mNotificationManager.setNotificationPolicy(mPolicy); 157 } 158 getNewSuppressedEffects(boolean suppress, int effectType)159 private int getNewSuppressedEffects(boolean suppress, int effectType) { 160 int effects = mPolicy.suppressedVisualEffects; 161 162 if (suppress) { 163 effects |= effectType; 164 } else { 165 effects &= ~effectType; 166 } 167 168 return clearDeprecatedEffects(effects); 169 } 170 clearDeprecatedEffects(int effects)171 private int clearDeprecatedEffects(int effects) { 172 return effects & ~(SUPPRESSED_EFFECT_SCREEN_ON | SUPPRESSED_EFFECT_SCREEN_OFF); 173 } 174 isEffectAllowed(int effect)175 protected boolean isEffectAllowed(int effect) { 176 return (mPolicy.suppressedVisualEffects & effect) == 0; 177 } 178 saveSenders(int category, int val)179 protected void saveSenders(int category, int val) { 180 int priorityCallSenders = getPriorityCallSenders(); 181 int priorityMessagesSenders = getPriorityMessageSenders(); 182 int categorySenders = getPrioritySenders(category); 183 184 final boolean allowSenders = val != SOURCE_NONE; 185 final int allowSendersFrom = val == SOURCE_NONE ? categorySenders : val; 186 187 String stringCategory = ""; 188 if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) { 189 stringCategory = "Calls"; 190 priorityCallSenders = allowSendersFrom; 191 } 192 193 if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) { 194 stringCategory = "Messages"; 195 priorityMessagesSenders = allowSendersFrom; 196 } 197 198 savePolicy(getNewPriorityCategories(allowSenders, category), 199 priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects); 200 201 if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" + 202 stringCategory + "=" + allowSenders + " allow" + stringCategory + "From=" 203 + ZenModeConfig.sourceToString(allowSendersFrom)); 204 } 205 getSendersKey(int category)206 protected String getSendersKey(int category) { 207 switch (getZenMode()) { 208 case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: 209 case Settings.Global.ZEN_MODE_ALARMS: 210 return getKeyFromSetting(SOURCE_NONE); 211 default: 212 int prioritySenders = getPrioritySenders(category); 213 return getKeyFromSetting(isPriorityCategoryEnabled(category) 214 ? prioritySenders : SOURCE_NONE); 215 } 216 } 217 getPrioritySenders(int category)218 private int getPrioritySenders(int category) { 219 int categorySenders = -1; 220 221 if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) { 222 return getPriorityCallSenders(); 223 } 224 225 if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) { 226 return getPriorityMessageSenders(); 227 } 228 229 return categorySenders; 230 } 231 getKeyFromSetting(int contactType)232 protected static String getKeyFromSetting(int contactType) { 233 switch (contactType) { 234 case NotificationManager.Policy.PRIORITY_SENDERS_ANY: 235 return ZEN_MODE_FROM_ANYONE; 236 case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS: 237 return ZEN_MODE_FROM_CONTACTS; 238 case NotificationManager.Policy.PRIORITY_SENDERS_STARRED: 239 return ZEN_MODE_FROM_STARRED; 240 case SOURCE_NONE: 241 default: 242 return ZEN_MODE_FROM_NONE; 243 } 244 } 245 getContactsSummary(int category)246 protected int getContactsSummary(int category) { 247 int contactType = -1; 248 249 // SOURCE_NONE can be used when in total silence or alarms only 250 // (policy is based on user's preferences but the UI displayed is based on zenMode) 251 if (category == SOURCE_NONE) { 252 return R.string.zen_mode_from_none; 253 } 254 255 if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) { 256 if (isPriorityCategoryEnabled(category)) { 257 contactType = getPriorityMessageSenders(); 258 } 259 } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) { 260 if (isPriorityCategoryEnabled(category)) { 261 contactType = getPriorityCallSenders(); 262 } 263 } 264 265 switch (contactType) { 266 case NotificationManager.Policy.PRIORITY_SENDERS_ANY: 267 return R.string.zen_mode_from_anyone; 268 case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS: 269 return R.string.zen_mode_from_contacts; 270 case NotificationManager.Policy.PRIORITY_SENDERS_STARRED: 271 return R.string.zen_mode_from_starred; 272 case SOURCE_NONE: 273 default: 274 return R.string.zen_mode_from_none; 275 } 276 } 277 getSettingFromPrefKey(String key)278 protected static int getSettingFromPrefKey(String key) { 279 switch (key) { 280 case ZEN_MODE_FROM_ANYONE: 281 return NotificationManager.Policy.PRIORITY_SENDERS_ANY; 282 case ZEN_MODE_FROM_CONTACTS: 283 return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; 284 case ZEN_MODE_FROM_STARRED: 285 return NotificationManager.Policy.PRIORITY_SENDERS_STARRED; 286 case ZEN_MODE_FROM_NONE: 287 default: 288 return SOURCE_NONE; 289 } 290 } 291 removeZenRule(String ruleId)292 public boolean removeZenRule(String ruleId) { 293 return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId); 294 } 295 addZenRule(AutomaticZenRule rule)296 protected String addZenRule(AutomaticZenRule rule) { 297 try { 298 String id = NotificationManager.from(mContext).addAutomaticZenRule(rule); 299 NotificationManager.from(mContext).getAutomaticZenRule(id); 300 return id; 301 } catch (Exception e) { 302 return null; 303 } 304 } 305 } 306