1 /** 2 * Copyright (c) 2015, 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 android.app; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.NotificationManager.InterruptionFilter; 22 import android.content.ComponentName; 23 import android.net.Uri; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.service.notification.Condition; 27 import android.service.notification.ZenPolicy; 28 29 import java.util.Objects; 30 31 /** 32 * Rule instance information for zen mode. 33 */ 34 public final class AutomaticZenRule implements Parcelable { 35 /* @hide */ 36 private static final int ENABLED = 1; 37 /* @hide */ 38 private static final int DISABLED = 0; 39 private boolean enabled = false; 40 private String name; 41 private @InterruptionFilter int interruptionFilter; 42 private Uri conditionId; 43 private ComponentName owner; 44 private ComponentName configurationActivity; 45 private long creationTime; 46 private ZenPolicy mZenPolicy; 47 private boolean mModified = false; 48 private String mPkg; 49 50 /** 51 * The maximum string length for any string contained in this automatic zen rule. This pertains 52 * both to fields in the rule itself (such as its name) and items with sub-fields. 53 * @hide 54 */ 55 public static final int MAX_STRING_LENGTH = 1000; 56 57 /** 58 * Creates an automatic zen rule. 59 * 60 * @param name The name of the rule. 61 * @param owner The Condition Provider service that owns this rule. 62 * @param interruptionFilter The interruption filter defines which notifications are allowed to 63 * interrupt the user (e.g. via sound & vibration) while this rule 64 * is active. 65 * @param enabled Whether the rule is enabled. 66 * @deprecated use {@link #AutomaticZenRule(String, ComponentName, ComponentName, Uri, 67 * ZenPolicy, int, boolean)}. 68 */ 69 @Deprecated AutomaticZenRule(String name, ComponentName owner, Uri conditionId, int interruptionFilter, boolean enabled)70 public AutomaticZenRule(String name, ComponentName owner, Uri conditionId, 71 int interruptionFilter, boolean enabled) { 72 this(name, owner, null, conditionId, null, interruptionFilter, enabled); 73 } 74 75 /** 76 * Creates an automatic zen rule. 77 * 78 * @param name The name of the rule. 79 * @param owner The Condition Provider service that owns this rule. This can be null if you're 80 * using {@link NotificationManager#setAutomaticZenRuleState(String, Condition)} 81 * instead of {@link android.service.notification.ConditionProviderService}. 82 * @param configurationActivity An activity that handles 83 * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows 84 * the user 85 * more information about this rule and/or allows them to 86 * configure it. This is required if you are not using a 87 * {@link android.service.notification.ConditionProviderService}. 88 * If you are, it overrides the information specified in your 89 * manifest. 90 * @param conditionId A representation of the state that should cause your app to apply the 91 * given interruption filter. 92 * @param interruptionFilter The interruption filter defines which notifications are allowed to 93 * interrupt the user (e.g. via sound & vibration) while this rule 94 * is active. 95 * @param policy The policy defines which notifications are allowed to interrupt the user 96 * while this rule is active. This overrides the global policy while this rule is 97 * action ({@link Condition#STATE_TRUE}). 98 * @param enabled Whether the rule is enabled. 99 */ AutomaticZenRule(@onNull String name, @Nullable ComponentName owner, @Nullable ComponentName configurationActivity, @NonNull Uri conditionId, @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled)100 public AutomaticZenRule(@NonNull String name, @Nullable ComponentName owner, 101 @Nullable ComponentName configurationActivity, @NonNull Uri conditionId, 102 @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled) { 103 this.name = getTrimmedString(name); 104 this.owner = getTrimmedComponentName(owner); 105 this.configurationActivity = getTrimmedComponentName(configurationActivity); 106 this.conditionId = getTrimmedUri(conditionId); 107 this.interruptionFilter = interruptionFilter; 108 this.enabled = enabled; 109 this.mZenPolicy = policy; 110 } 111 112 /** 113 * @hide 114 */ AutomaticZenRule(String name, ComponentName owner, ComponentName configurationActivity, Uri conditionId, ZenPolicy policy, int interruptionFilter, boolean enabled, long creationTime)115 public AutomaticZenRule(String name, ComponentName owner, ComponentName configurationActivity, 116 Uri conditionId, ZenPolicy policy, int interruptionFilter, boolean enabled, 117 long creationTime) { 118 this(name, owner, configurationActivity, conditionId, policy, interruptionFilter, enabled); 119 this.creationTime = creationTime; 120 } 121 AutomaticZenRule(Parcel source)122 public AutomaticZenRule(Parcel source) { 123 enabled = source.readInt() == ENABLED; 124 if (source.readInt() == ENABLED) { 125 name = getTrimmedString(source.readString()); 126 } 127 interruptionFilter = source.readInt(); 128 conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class)); 129 owner = getTrimmedComponentName( 130 source.readParcelable(null, android.content.ComponentName.class)); 131 configurationActivity = getTrimmedComponentName( 132 source.readParcelable(null, android.content.ComponentName.class)); 133 creationTime = source.readLong(); 134 mZenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); 135 mModified = source.readInt() == ENABLED; 136 mPkg = source.readString(); 137 } 138 139 /** 140 * Returns the {@link ComponentName} of the condition provider service that owns this rule. 141 */ getOwner()142 public ComponentName getOwner() { 143 return owner; 144 } 145 146 /** 147 * Returns the {@link ComponentName} of the activity that shows configuration options 148 * for this rule. 149 */ getConfigurationActivity()150 public @Nullable ComponentName getConfigurationActivity() { 151 return configurationActivity; 152 } 153 154 /** 155 * Returns the representation of the state that causes this rule to become active. 156 */ getConditionId()157 public Uri getConditionId() { 158 return conditionId; 159 } 160 161 /** 162 * Returns the interruption filter that is applied when this rule is active. 163 */ getInterruptionFilter()164 public int getInterruptionFilter() { 165 return interruptionFilter; 166 } 167 168 /** 169 * Returns the name of this rule. 170 */ getName()171 public String getName() { 172 return name; 173 } 174 175 /** 176 * Returns whether this rule is enabled. 177 */ isEnabled()178 public boolean isEnabled() { 179 return enabled; 180 } 181 182 /** 183 * Returns whether this rule's name has been modified by the user. 184 * @hide 185 */ isModified()186 public boolean isModified() { 187 return mModified; 188 } 189 190 /** 191 * Gets the zen policy. 192 */ getZenPolicy()193 public ZenPolicy getZenPolicy() { 194 return mZenPolicy == null ? null : this.mZenPolicy.copy(); 195 } 196 197 /** 198 * Returns the time this rule was created, represented as milliseconds since the epoch. 199 */ getCreationTime()200 public long getCreationTime() { 201 return creationTime; 202 } 203 204 /** 205 * Sets the representation of the state that causes this rule to become active. 206 */ setConditionId(Uri conditionId)207 public void setConditionId(Uri conditionId) { 208 this.conditionId = getTrimmedUri(conditionId); 209 } 210 211 /** 212 * Sets the interruption filter that is applied when this rule is active. 213 * @param interruptionFilter The do not disturb mode to enter when this rule is active. 214 */ setInterruptionFilter(@nterruptionFilter int interruptionFilter)215 public void setInterruptionFilter(@InterruptionFilter int interruptionFilter) { 216 this.interruptionFilter = interruptionFilter; 217 } 218 219 /** 220 * Sets the name of this rule. 221 */ setName(String name)222 public void setName(String name) { 223 this.name = getTrimmedString(name); 224 } 225 226 /** 227 * Enables this rule. 228 */ setEnabled(boolean enabled)229 public void setEnabled(boolean enabled) { 230 this.enabled = enabled; 231 } 232 233 /** 234 * Sets modified state of this rule. 235 * @hide 236 */ setModified(boolean modified)237 public void setModified(boolean modified) { 238 this.mModified = modified; 239 } 240 241 /** 242 * Sets the zen policy. 243 */ setZenPolicy(ZenPolicy zenPolicy)244 public void setZenPolicy(ZenPolicy zenPolicy) { 245 this.mZenPolicy = (zenPolicy == null ? null : zenPolicy.copy()); 246 } 247 248 /** 249 * Sets the configuration activity - an activity that handles 250 * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows the user more information 251 * about this rule and/or allows them to configure it. This is required to be non-null for rules 252 * that are not backed by {@link android.service.notification.ConditionProviderService}. 253 */ setConfigurationActivity(@ullable ComponentName componentName)254 public void setConfigurationActivity(@Nullable ComponentName componentName) { 255 this.configurationActivity = getTrimmedComponentName(componentName); 256 } 257 258 /** 259 * @hide 260 */ setPackageName(String pkgName)261 public void setPackageName(String pkgName) { 262 mPkg = pkgName; 263 } 264 265 /** 266 * @hide 267 */ getPackageName()268 public String getPackageName() { 269 return mPkg; 270 } 271 272 @Override describeContents()273 public int describeContents() { 274 return 0; 275 } 276 277 @Override writeToParcel(Parcel dest, int flags)278 public void writeToParcel(Parcel dest, int flags) { 279 dest.writeInt(enabled ? ENABLED : DISABLED); 280 if (name != null) { 281 dest.writeInt(1); 282 dest.writeString(name); 283 } else { 284 dest.writeInt(0); 285 } 286 dest.writeInt(interruptionFilter); 287 dest.writeParcelable(conditionId, 0); 288 dest.writeParcelable(owner, 0); 289 dest.writeParcelable(configurationActivity, 0); 290 dest.writeLong(creationTime); 291 dest.writeParcelable(mZenPolicy, 0); 292 dest.writeInt(mModified ? ENABLED : DISABLED); 293 dest.writeString(mPkg); 294 } 295 296 @Override toString()297 public String toString() { 298 return new StringBuilder(AutomaticZenRule.class.getSimpleName()).append('[') 299 .append("enabled=").append(enabled) 300 .append(",name=").append(name) 301 .append(",interruptionFilter=").append(interruptionFilter) 302 .append(",pkg=").append(mPkg) 303 .append(",conditionId=").append(conditionId) 304 .append(",owner=").append(owner) 305 .append(",configActivity=").append(configurationActivity) 306 .append(",creationTime=").append(creationTime) 307 .append(",mZenPolicy=").append(mZenPolicy) 308 .append(']').toString(); 309 } 310 311 @Override equals(@ullable Object o)312 public boolean equals(@Nullable Object o) { 313 if (!(o instanceof AutomaticZenRule)) return false; 314 if (o == this) return true; 315 final AutomaticZenRule other = (AutomaticZenRule) o; 316 return other.enabled == enabled 317 && other.mModified == mModified 318 && Objects.equals(other.name, name) 319 && other.interruptionFilter == interruptionFilter 320 && Objects.equals(other.conditionId, conditionId) 321 && Objects.equals(other.owner, owner) 322 && Objects.equals(other.mZenPolicy, mZenPolicy) 323 && Objects.equals(other.configurationActivity, configurationActivity) 324 && Objects.equals(other.mPkg, mPkg) 325 && other.creationTime == creationTime; 326 } 327 328 @Override hashCode()329 public int hashCode() { 330 return Objects.hash(enabled, name, interruptionFilter, conditionId, owner, 331 configurationActivity, mZenPolicy, mModified, creationTime, mPkg); 332 } 333 334 public static final @android.annotation.NonNull Parcelable.Creator<AutomaticZenRule> CREATOR 335 = new Parcelable.Creator<AutomaticZenRule>() { 336 @Override 337 public AutomaticZenRule createFromParcel(Parcel source) { 338 return new AutomaticZenRule(source); 339 } 340 @Override 341 public AutomaticZenRule[] newArray(int size) { 342 return new AutomaticZenRule[size]; 343 } 344 }; 345 346 /** 347 * If the package or class name of the provided ComponentName are longer than MAX_STRING_LENGTH, 348 * return a trimmed version that truncates each of the package and class name at the max length. 349 */ getTrimmedComponentName(ComponentName cn)350 private static ComponentName getTrimmedComponentName(ComponentName cn) { 351 if (cn == null) return null; 352 return new ComponentName(getTrimmedString(cn.getPackageName()), 353 getTrimmedString(cn.getClassName())); 354 } 355 356 /** 357 * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH. 358 */ getTrimmedString(String input)359 private static String getTrimmedString(String input) { 360 if (input != null && input.length() > MAX_STRING_LENGTH) { 361 return input.substring(0, MAX_STRING_LENGTH); 362 } 363 return input; 364 } 365 366 /** 367 * Returns a truncated copy of the Uri by trimming the string representation to the maximum 368 * string length. 369 */ getTrimmedUri(Uri input)370 private static Uri getTrimmedUri(Uri input) { 371 if (input != null && input.toString().length() > MAX_STRING_LENGTH) { 372 return Uri.parse(getTrimmedString(input.toString())); 373 } 374 return input; 375 } 376 } 377