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 static com.android.internal.util.Preconditions.checkArgument; 20 21 import android.annotation.DrawableRes; 22 import android.annotation.IntDef; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.app.NotificationManager.InterruptionFilter; 26 import android.content.ComponentName; 27 import android.net.Uri; 28 import android.os.Parcel; 29 import android.os.Parcelable; 30 import android.service.notification.Condition; 31 import android.service.notification.ZenDeviceEffects; 32 import android.service.notification.ZenPolicy; 33 import android.view.WindowInsetsController; 34 35 import java.lang.annotation.Retention; 36 import java.lang.annotation.RetentionPolicy; 37 import java.util.ArrayList; 38 import java.util.Objects; 39 40 /** 41 * Rule instance information for a zen (aka DND or Attention Management) mode. 42 */ 43 public final class AutomaticZenRule implements Parcelable { 44 /* @hide */ 45 private static final int ENABLED = 1; 46 /* @hide */ 47 private static final int DISABLED = 0; 48 49 /** 50 * Rule is of an unknown type. This is the default value if not provided by the owning app, 51 * and the value returned if the true type was added in an API level higher than the calling 52 * app's targetSdk. 53 */ 54 public static final int TYPE_UNKNOWN = -1; 55 /** 56 * Rule is of a known type, but not one of the specific types. 57 */ 58 public static final int TYPE_OTHER = 0; 59 /** 60 * The type for rules triggered according to a time-based schedule. 61 */ 62 public static final int TYPE_SCHEDULE_TIME = 1; 63 /** 64 * The type for rules triggered by calendar events. 65 */ 66 public static final int TYPE_SCHEDULE_CALENDAR = 2; 67 /** 68 * The type for rules triggered by bedtime/sleeping, like time of day, or snore detection. 69 * 70 * <p>Only the 'Wellbeing' app may own rules of this type. 71 */ 72 public static final int TYPE_BEDTIME = 3; 73 /** 74 * The type for rules triggered by driving detection, like Bluetooth connections or vehicle 75 * sounds. 76 */ 77 public static final int TYPE_DRIVING = 4; 78 /** 79 * The type for rules triggered by the user entering an immersive activity, like opening an app 80 * using {@link WindowInsetsController#hide(int)}. 81 */ 82 public static final int TYPE_IMMERSIVE = 5; 83 /** 84 * The type for rules that have a {@link ZenPolicy} that implies that the 85 * device should not make sound and potentially hide some visual effects; may be triggered 86 * when entering a location where silence is requested, like a theater. 87 */ 88 public static final int TYPE_THEATER = 6; 89 /** 90 * The type for rules created and managed by a device owner. These rules may not be fully 91 * editable by the device user. 92 * 93 * <p>Only a 'Device Owner' app may own rules of this type. 94 */ 95 public static final int TYPE_MANAGED = 7; 96 97 /** @hide */ 98 @IntDef(prefix = { "TYPE_" }, value = { 99 TYPE_UNKNOWN, TYPE_OTHER, TYPE_SCHEDULE_TIME, TYPE_SCHEDULE_CALENDAR, TYPE_BEDTIME, 100 TYPE_DRIVING, TYPE_IMMERSIVE, TYPE_THEATER, TYPE_MANAGED 101 }) 102 @Retention(RetentionPolicy.SOURCE) 103 public @interface Type {} 104 105 /** 106 * Enum for the user-modifiable fields in this object. 107 * @hide 108 */ 109 @IntDef(flag = true, prefix = { "FIELD_" }, value = { 110 FIELD_NAME, 111 FIELD_INTERRUPTION_FILTER, 112 FIELD_ICON 113 }) 114 @Retention(RetentionPolicy.SOURCE) 115 public @interface ModifiableField {} 116 117 /** 118 * @hide 119 */ 120 public static final int FIELD_NAME = 1 << 0; 121 /** 122 * @hide 123 */ 124 public static final int FIELD_INTERRUPTION_FILTER = 1 << 1; 125 /** 126 * @hide 127 */ 128 public static final int FIELD_ICON = 1 << 2; 129 130 private boolean enabled; 131 private String name; 132 private @InterruptionFilter int interruptionFilter; 133 private Uri conditionId; 134 private ComponentName owner; 135 private ComponentName configurationActivity; 136 private long creationTime; 137 private ZenPolicy mZenPolicy; 138 private ZenDeviceEffects mDeviceEffects; 139 private String mPkg; 140 private int mType = TYPE_UNKNOWN; 141 private int mIconResId; 142 private String mTriggerDescription; 143 private boolean mAllowManualInvocation; 144 145 /** 146 * The maximum string length for any string contained in this automatic zen rule. This pertains 147 * both to fields in the rule itself (such as its name) and items with sub-fields. 148 * @hide 149 */ 150 public static final int MAX_STRING_LENGTH = 500; 151 152 /** 153 * The maximum string length for the trigger description rule, given UI constraints. 154 * @hide 155 */ 156 public static final int MAX_DESC_LENGTH = 150; 157 158 /** 159 * Creates an automatic zen rule. 160 * 161 * @param name The name of the rule. 162 * @param owner The Condition Provider service that owns this rule. 163 * @param interruptionFilter The interruption filter defines which notifications are allowed to 164 * interrupt the user (e.g. via sound & vibration) while this rule 165 * is active. 166 * @param enabled Whether the rule is enabled. 167 * 168 * @deprecated Use {@link AutomaticZenRule.Builder} to construct an {@link AutomaticZenRule}. 169 */ 170 @Deprecated AutomaticZenRule(String name, ComponentName owner, Uri conditionId, int interruptionFilter, boolean enabled)171 public AutomaticZenRule(String name, ComponentName owner, Uri conditionId, 172 int interruptionFilter, boolean enabled) { 173 this(name, owner, null, conditionId, null, interruptionFilter, enabled); 174 } 175 176 /** 177 * Creates an automatic zen rule. 178 * 179 * <p>Note: Prefer {@link AutomaticZenRule.Builder} to construct an {@link AutomaticZenRule}. 180 * 181 * @param name The name of the rule. 182 * @param owner The Condition Provider service that owns this rule. This can be null if you're 183 * using {@link NotificationManager#setAutomaticZenRuleState(String, Condition)} 184 * instead of {@link android.service.notification.ConditionProviderService}. 185 * @param configurationActivity An activity that handles 186 * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows 187 * the user 188 * more information about this rule and/or allows them to 189 * configure it. This is required if you are not using a 190 * {@link android.service.notification.ConditionProviderService}. 191 * If you are, it overrides the information specified in your 192 * manifest. 193 * @param conditionId A representation of the state that should cause your app to apply the 194 * given interruption filter. 195 * @param interruptionFilter The interruption filter defines which notifications are allowed to 196 * interrupt the user (e.g. via sound & vibration) while this rule 197 * is active. 198 * @param policy The policy defines which notifications are allowed to interrupt the user 199 * while this rule is active. This overrides the global policy while this rule is 200 * action ({@link Condition#STATE_TRUE}). 201 * @param enabled Whether the rule is enabled. 202 */ AutomaticZenRule(@onNull String name, @Nullable ComponentName owner, @Nullable ComponentName configurationActivity, @NonNull Uri conditionId, @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled)203 public AutomaticZenRule(@NonNull String name, @Nullable ComponentName owner, 204 @Nullable ComponentName configurationActivity, @NonNull Uri conditionId, 205 @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled) { 206 this.name = getTrimmedString(name); 207 this.owner = getTrimmedComponentName(owner); 208 this.configurationActivity = getTrimmedComponentName(configurationActivity); 209 this.conditionId = getTrimmedUri(conditionId); 210 this.interruptionFilter = interruptionFilter; 211 this.enabled = enabled; 212 this.mZenPolicy = policy; 213 } 214 215 /** 216 * @hide 217 * @deprecated Do not add new usages; will be removed soon. 218 */ 219 // TODO: b/368247671 - Remove when modes_ui is inlined (remaining usages are in obsolete tests) 220 @Deprecated AutomaticZenRule(String name, ComponentName owner, ComponentName configurationActivity, Uri conditionId, ZenPolicy policy, int interruptionFilter, boolean enabled, long creationTime)221 public AutomaticZenRule(String name, ComponentName owner, ComponentName configurationActivity, 222 Uri conditionId, ZenPolicy policy, int interruptionFilter, boolean enabled, 223 long creationTime) { 224 this(name, owner, configurationActivity, conditionId, policy, interruptionFilter, enabled); 225 this.creationTime = creationTime; 226 } 227 AutomaticZenRule(Parcel source)228 public AutomaticZenRule(Parcel source) { 229 enabled = source.readInt() == ENABLED; 230 if (source.readInt() == ENABLED) { 231 name = getTrimmedString(source.readString8()); 232 } 233 interruptionFilter = source.readInt(); 234 conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class)); 235 owner = getTrimmedComponentName( 236 source.readParcelable(null, android.content.ComponentName.class)); 237 configurationActivity = getTrimmedComponentName( 238 source.readParcelable(null, android.content.ComponentName.class)); 239 creationTime = source.readLong(); 240 mZenPolicy = source.readParcelable(null, ZenPolicy.class); 241 mPkg = source.readString8(); 242 mDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); 243 mAllowManualInvocation = source.readBoolean(); 244 mIconResId = source.readInt(); 245 mTriggerDescription = getTrimmedString(source.readString8(), MAX_DESC_LENGTH); 246 mType = source.readInt(); 247 } 248 249 /** 250 * Returns the {@link ComponentName} of the condition provider service that owns this rule. 251 */ getOwner()252 public ComponentName getOwner() { 253 return owner; 254 } 255 256 /** 257 * Returns the {@link ComponentName} of the activity that shows configuration options 258 * for this rule. 259 */ getConfigurationActivity()260 public @Nullable ComponentName getConfigurationActivity() { 261 return configurationActivity; 262 } 263 264 /** 265 * Returns the representation of the state that causes this rule to become active. 266 */ getConditionId()267 public Uri getConditionId() { 268 return conditionId; 269 } 270 271 /** 272 * Returns the interruption filter that is applied when this rule is active. 273 */ getInterruptionFilter()274 public int getInterruptionFilter() { 275 return interruptionFilter; 276 } 277 278 /** 279 * Returns the name of this rule. 280 */ getName()281 public String getName() { 282 return name; 283 } 284 285 /** 286 * Returns whether this rule is enabled. 287 */ isEnabled()288 public boolean isEnabled() { 289 return enabled; 290 } 291 292 /** 293 * Gets the {@link ZenPolicy} applied if {@link #getInterruptionFilter()} is 294 * {@link NotificationManager#INTERRUPTION_FILTER_PRIORITY}. 295 */ 296 @Nullable getZenPolicy()297 public ZenPolicy getZenPolicy() { 298 return mZenPolicy == null ? null : this.mZenPolicy.copy(); 299 } 300 301 /** Gets the {@link ZenDeviceEffects} of this rule. */ 302 @Nullable getDeviceEffects()303 public ZenDeviceEffects getDeviceEffects() { 304 return mDeviceEffects; 305 } 306 307 /** 308 * Returns the time this rule was created, represented as milliseconds since the epoch. 309 */ getCreationTime()310 public long getCreationTime() { 311 return creationTime; 312 } 313 314 /** 315 * Sets the representation of the state that causes this rule to become active. 316 */ setConditionId(Uri conditionId)317 public void setConditionId(Uri conditionId) { 318 this.conditionId = getTrimmedUri(conditionId); 319 } 320 321 /** 322 * Sets the interruption filter that is applied when this rule is active. 323 * 324 * <ul> 325 * <li>When {@link NotificationManager#INTERRUPTION_FILTER_PRIORITY}, the rule will use 326 * the {@link ZenPolicy} supplied to {@link #setZenPolicy} (or a default one). 327 * <li>When {@link NotificationManager#INTERRUPTION_FILTER_ALARMS} or 328 * {@link NotificationManager#INTERRUPTION_FILTER_NONE}, the rule will use a fixed 329 * {@link ZenPolicy} matching the filter. 330 * <li>When {@link NotificationManager#INTERRUPTION_FILTER_ALL}, the rule will not block 331 * notifications, but can still have {@link ZenDeviceEffects}. 332 * </ul> 333 * 334 * @param interruptionFilter The do not disturb mode to enter when this rule is active. 335 */ setInterruptionFilter(@nterruptionFilter int interruptionFilter)336 public void setInterruptionFilter(@InterruptionFilter int interruptionFilter) { 337 this.interruptionFilter = interruptionFilter; 338 } 339 340 /** 341 * Sets the name of this rule. 342 */ setName(String name)343 public void setName(String name) { 344 this.name = getTrimmedString(name); 345 } 346 347 /** 348 * Enables this rule. 349 */ setEnabled(boolean enabled)350 public void setEnabled(boolean enabled) { 351 this.enabled = enabled; 352 } 353 354 /** 355 * Sets the {@link ZenPolicy} applied if {@link #getInterruptionFilter()} is 356 * {@link NotificationManager#INTERRUPTION_FILTER_PRIORITY}. 357 * 358 * <p>When updating an existing rule via {@link NotificationManager#updateAutomaticZenRule}, 359 * a {@code null} value here means the previous policy is retained. 360 */ setZenPolicy(@ullable ZenPolicy zenPolicy)361 public void setZenPolicy(@Nullable ZenPolicy zenPolicy) { 362 this.mZenPolicy = (zenPolicy == null ? null : zenPolicy.copy()); 363 } 364 365 /** 366 * Sets the {@link ZenDeviceEffects} associated to this rule. Device effects specify changes to 367 * the device behavior that should apply while the rule is active, but are not directly related 368 * to suppressing notifications (for example: disabling always-on display). 369 * 370 * <p>When updating an existing rule via {@link NotificationManager#updateAutomaticZenRule}, 371 * a {@code null} value here means the previous set of effects is retained. 372 */ setDeviceEffects(@ullable ZenDeviceEffects deviceEffects)373 public void setDeviceEffects(@Nullable ZenDeviceEffects deviceEffects) { 374 mDeviceEffects = deviceEffects; 375 } 376 377 /** 378 * Sets the component name of the 379 * {@link android.service.notification.ConditionProviderService} that manages this rule 380 * (but note that {@link android.service.notification.ConditionProviderService} is 381 * deprecated in favor of using {@link NotificationManager#setAutomaticZenRuleState} to 382 * notify the system about the state of your rule). 383 * 384 * <p>This is exclusive with {@link #setConfigurationActivity}; rules where a configuration 385 * activity is set will not use the component set here to determine whether the rule 386 * should be active. 387 * 388 * @hide 389 */ setOwner(@ullable ComponentName owner)390 public void setOwner(@Nullable ComponentName owner) { 391 this.owner = owner; 392 } 393 394 /** 395 * Sets the configuration activity - an activity that handles 396 * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows the user more information 397 * about this rule and/or allows them to configure it. This is required to be non-null for rules 398 * that are not backed by a {@link android.service.notification.ConditionProviderService}. 399 * 400 * <p>This is exclusive with the {@code owner} supplied in the constructor; rules where a 401 * configuration activity is set will not use the 402 * {@link android.service.notification.ConditionProviderService} supplied there to determine 403 * whether the rule should be active. 404 */ setConfigurationActivity(@ullable ComponentName componentName)405 public void setConfigurationActivity(@Nullable ComponentName componentName) { 406 this.configurationActivity = getTrimmedComponentName(componentName); 407 } 408 409 /** 410 * @hide 411 */ setPackageName(String pkgName)412 public void setPackageName(String pkgName) { 413 mPkg = pkgName; 414 } 415 416 /** 417 * @hide 418 */ getPackageName()419 public String getPackageName() { 420 return mPkg; 421 } 422 423 /** 424 * Gets the type of the rule. 425 */ getType()426 public @Type int getType() { 427 return mType; 428 } 429 430 /** 431 * Sets the type of the rule. 432 * @hide 433 */ setType(@ype int type)434 public void setType(@Type int type) { 435 mType = checkValidType(type); 436 } 437 438 /** 439 * Gets the user visible description of when this rule is active 440 * (see {@link Condition#STATE_TRUE}). 441 */ getTriggerDescription()442 public @Nullable String getTriggerDescription() { 443 return mTriggerDescription; 444 } 445 446 /** 447 * Sets a user visible description of when this rule will be active 448 * (see {@link Condition#STATE_TRUE}). 449 * 450 * A description should be a (localized) string like "Mon-Fri, 9pm-7am" or 451 * "When connected to [Car Name]". 452 * @hide 453 */ setTriggerDescription(@ullable String triggerDescription)454 public void setTriggerDescription(@Nullable String triggerDescription) { 455 mTriggerDescription = triggerDescription; 456 } 457 458 /** 459 * Gets the resource id of the drawable icon for this rule. 460 */ getIconResId()461 public @DrawableRes int getIconResId() { 462 return mIconResId; 463 } 464 465 /** 466 * Sets a resource id of a tintable vector drawable representing the rule in image form. 467 * @hide 468 */ setIconResId(int iconResId)469 public void setIconResId(int iconResId) { 470 mIconResId = iconResId; 471 } 472 473 /** 474 * Gets whether this rule can be manually activated by the user even when the triggering 475 * condition for the rule is not met. 476 */ isManualInvocationAllowed()477 public boolean isManualInvocationAllowed() { 478 return mAllowManualInvocation; 479 } 480 481 /** 482 * Sets whether this rule can be manually activated by the user even when the triggering 483 * condition for the rule is not met. 484 * @hide 485 */ setManualInvocationAllowed(boolean allowManualInvocation)486 public void setManualInvocationAllowed(boolean allowManualInvocation) { 487 mAllowManualInvocation = allowManualInvocation; 488 } 489 490 /** @hide */ validate()491 public void validate() { 492 checkValidType(mType); 493 if (mDeviceEffects != null) { 494 mDeviceEffects.validate(); 495 } 496 } 497 498 @Type checkValidType(@ype int type)499 private static int checkValidType(@Type int type) { 500 checkArgument(type >= TYPE_UNKNOWN && type <= TYPE_MANAGED, 501 "Rule type must be one of TYPE_UNKNOWN, TYPE_OTHER, TYPE_SCHEDULE_TIME, " 502 + "TYPE_SCHEDULE_CALENDAR, TYPE_BEDTIME, TYPE_DRIVING, TYPE_IMMERSIVE, " 503 + "TYPE_THEATER, or TYPE_MANAGED"); 504 return type; 505 } 506 507 @Override describeContents()508 public int describeContents() { 509 return 0; 510 } 511 512 @Override writeToParcel(Parcel dest, int flags)513 public void writeToParcel(Parcel dest, int flags) { 514 dest.writeInt(enabled ? ENABLED : DISABLED); 515 if (name != null) { 516 dest.writeInt(1); 517 dest.writeString8(name); 518 } else { 519 dest.writeInt(0); 520 } 521 dest.writeInt(interruptionFilter); 522 dest.writeParcelable(conditionId, 0); 523 dest.writeParcelable(owner, 0); 524 dest.writeParcelable(configurationActivity, 0); 525 dest.writeLong(creationTime); 526 dest.writeParcelable(mZenPolicy, 0); 527 dest.writeString8(mPkg); 528 dest.writeParcelable(mDeviceEffects, 0); 529 dest.writeBoolean(mAllowManualInvocation); 530 dest.writeInt(mIconResId); 531 dest.writeString8(mTriggerDescription); 532 dest.writeInt(mType); 533 } 534 535 @Override toString()536 public String toString() { 537 return new StringBuilder(AutomaticZenRule.class.getSimpleName()) 538 .append('[') 539 .append("enabled=").append(enabled) 540 .append(",name=").append(name) 541 .append(",type=").append(mType) 542 .append(",interruptionFilter=").append(interruptionFilter) 543 .append(",pkg=").append(mPkg) 544 .append(",conditionId=").append(conditionId) 545 .append(",owner=").append(owner) 546 .append(",configActivity=").append(configurationActivity) 547 .append(",creationTime=").append(creationTime) 548 .append(",mZenPolicy=").append(mZenPolicy) 549 .append(",deviceEffects=").append(mDeviceEffects) 550 .append(",allowManualInvocation=").append(mAllowManualInvocation) 551 .append(",iconResId=").append(mIconResId) 552 .append(",triggerDescription=").append(mTriggerDescription) 553 .append(']') 554 .toString(); 555 } 556 557 /** @hide */ fieldsToString(@odifiableField int bitmask)558 public static String fieldsToString(@ModifiableField int bitmask) { 559 ArrayList<String> modified = new ArrayList<>(); 560 if ((bitmask & FIELD_NAME) != 0) { 561 modified.add("FIELD_NAME"); 562 } 563 if ((bitmask & FIELD_INTERRUPTION_FILTER) != 0) { 564 modified.add("FIELD_INTERRUPTION_FILTER"); 565 } 566 if ((bitmask & FIELD_ICON) != 0) { 567 modified.add("FIELD_ICON"); 568 } 569 return "{" + String.join(",", modified) + "}"; 570 } 571 572 @Override equals(@ullable Object o)573 public boolean equals(@Nullable Object o) { 574 if (!(o instanceof AutomaticZenRule)) return false; 575 if (o == this) return true; 576 final AutomaticZenRule other = (AutomaticZenRule) o; 577 return other.enabled == enabled 578 && Objects.equals(other.name, name) 579 && other.interruptionFilter == interruptionFilter 580 && Objects.equals(other.conditionId, conditionId) 581 && Objects.equals(other.owner, owner) 582 && Objects.equals(other.mZenPolicy, mZenPolicy) 583 && Objects.equals(other.configurationActivity, configurationActivity) 584 && Objects.equals(other.mPkg, mPkg) 585 && other.creationTime == creationTime 586 && Objects.equals(other.mDeviceEffects, mDeviceEffects) 587 && other.mAllowManualInvocation == mAllowManualInvocation 588 && other.mIconResId == mIconResId 589 && Objects.equals(other.mTriggerDescription, mTriggerDescription) 590 && other.mType == mType; 591 } 592 593 @Override hashCode()594 public int hashCode() { 595 return Objects.hash(enabled, name, interruptionFilter, conditionId, owner, 596 configurationActivity, mZenPolicy, mDeviceEffects, creationTime, 597 mPkg, mAllowManualInvocation, mIconResId, mTriggerDescription, mType); 598 } 599 600 public static final @android.annotation.NonNull Parcelable.Creator<AutomaticZenRule> CREATOR 601 = new Parcelable.Creator<AutomaticZenRule>() { 602 @Override 603 public AutomaticZenRule createFromParcel(Parcel source) { 604 return new AutomaticZenRule(source); 605 } 606 @Override 607 public AutomaticZenRule[] newArray(int size) { 608 return new AutomaticZenRule[size]; 609 } 610 }; 611 612 /** 613 * If the package or class name of the provided ComponentName are longer than MAX_STRING_LENGTH, 614 * return a trimmed version that truncates each of the package and class name at the max length. 615 */ getTrimmedComponentName(ComponentName cn)616 private static ComponentName getTrimmedComponentName(ComponentName cn) { 617 if (cn == null) return null; 618 return new ComponentName(getTrimmedString(cn.getPackageName()), 619 getTrimmedString(cn.getClassName())); 620 } 621 622 /** 623 * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH. 624 */ getTrimmedString(String input)625 private static String getTrimmedString(String input) { 626 return getTrimmedString(input, MAX_STRING_LENGTH); 627 } 628 getTrimmedString(String input, int length)629 private static String getTrimmedString(String input, int length) { 630 if (input != null && input.length() > length) { 631 return input.substring(0, length); 632 } 633 return input; 634 } 635 636 /** 637 * Returns a truncated copy of the Uri by trimming the string representation to the maximum 638 * string length. 639 */ getTrimmedUri(Uri input)640 private static Uri getTrimmedUri(Uri input) { 641 if (input != null && input.toString().length() > MAX_STRING_LENGTH) { 642 return Uri.parse(getTrimmedString(input.toString())); 643 } 644 return input; 645 } 646 647 public static final class Builder { 648 private String mName; 649 private ComponentName mOwner; 650 private Uri mConditionId; 651 private int mInterruptionFilter = NotificationManager.INTERRUPTION_FILTER_PRIORITY; 652 private boolean mEnabled = true; 653 private ComponentName mConfigurationActivity = null; 654 private ZenPolicy mPolicy = null; 655 private ZenDeviceEffects mDeviceEffects = null; 656 private int mType = TYPE_UNKNOWN; 657 private String mDescription; 658 private int mIconResId; 659 private boolean mAllowManualInvocation; 660 private long mCreationTime; 661 private String mPkg; 662 Builder(@onNull AutomaticZenRule rule)663 public Builder(@NonNull AutomaticZenRule rule) { 664 mName = rule.getName(); 665 mOwner = rule.getOwner(); 666 mConditionId = rule.getConditionId(); 667 mInterruptionFilter = rule.getInterruptionFilter(); 668 mEnabled = rule.isEnabled(); 669 mConfigurationActivity = rule.getConfigurationActivity(); 670 mPolicy = rule.getZenPolicy(); 671 mDeviceEffects = rule.getDeviceEffects(); 672 mType = rule.getType(); 673 mDescription = rule.getTriggerDescription(); 674 mIconResId = rule.getIconResId(); 675 mAllowManualInvocation = rule.isManualInvocationAllowed(); 676 mCreationTime = rule.getCreationTime(); 677 mPkg = rule.getPackageName(); 678 } 679 Builder(@onNull String name, @NonNull Uri conditionId)680 public Builder(@NonNull String name, @NonNull Uri conditionId) { 681 mName = Objects.requireNonNull(name); 682 mConditionId = Objects.requireNonNull(conditionId); 683 } 684 685 /** 686 * Sets the name of this rule. 687 */ setName(@onNull String name)688 public @NonNull Builder setName(@NonNull String name) { 689 mName = name; 690 return this; 691 } 692 693 /** 694 * Sets the component name of the 695 * {@link android.service.notification.ConditionProviderService} that manages this rule 696 * (but note that {@link android.service.notification.ConditionProviderService} is 697 * deprecated in favor of using {@link NotificationManager#setAutomaticZenRuleState} to 698 * notify the system about the state of your rule). 699 * 700 * <p>This is exclusive with {@link #setConfigurationActivity}; rules where a configuration 701 * activity is set will not use the component set here to determine whether the rule 702 * should be active. 703 */ setOwner(@ullable ComponentName owner)704 public @NonNull Builder setOwner(@Nullable ComponentName owner) { 705 mOwner = owner; 706 return this; 707 } 708 709 /** 710 * Sets the representation of the state that causes this rule to become active. 711 */ setConditionId(@onNull Uri conditionId)712 public @NonNull Builder setConditionId(@NonNull Uri conditionId) { 713 mConditionId = conditionId; 714 return this; 715 } 716 717 /** 718 * Sets the interruption filter that is applied when this rule is active. 719 */ setInterruptionFilter( @nterruptionFilter int interruptionFilter)720 public @NonNull Builder setInterruptionFilter( 721 @InterruptionFilter int interruptionFilter) { 722 mInterruptionFilter = interruptionFilter; 723 return this; 724 } 725 726 /** 727 * Enables this rule. Rules are enabled by default. 728 */ setEnabled(boolean enabled)729 public @NonNull Builder setEnabled(boolean enabled) { 730 mEnabled = enabled; 731 return this; 732 } 733 734 /** 735 * Sets the configuration activity - an activity that handles 736 * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows the user more 737 * information about this rule and/or allows them to configure it. This is required to be 738 * non-null for rules that are not backed by a 739 * {@link android.service.notification.ConditionProviderService}. 740 * 741 * <p>This is exclusive with {@link #setOwner}; rules where a configuration 742 * activity is set will not use the 743 * {@link android.service.notification.ConditionProviderService} supplied there to determine 744 * whether the rule should be active. 745 */ setConfigurationActivity( @ullable ComponentName configurationActivity)746 public @NonNull Builder setConfigurationActivity( 747 @Nullable ComponentName configurationActivity) { 748 mConfigurationActivity = configurationActivity; 749 return this; 750 } 751 752 /** 753 * Sets the zen policy. 754 * 755 * <p>When updating an existing rule via {@link NotificationManager#updateAutomaticZenRule}, 756 * a {@code null} value here means the previous policy is retained. 757 */ setZenPolicy(@ullable ZenPolicy policy)758 public @NonNull Builder setZenPolicy(@Nullable ZenPolicy policy) { 759 mPolicy = policy; 760 return this; 761 } 762 763 /** 764 * Sets the {@link ZenDeviceEffects} associated to this rule. Device effects specify changes 765 * to the device behavior that should apply while the rule is active, but are not directly 766 * related to suppressing notifications (for example: disabling always-on display). 767 * 768 * <p>When updating an existing rule via {@link NotificationManager#updateAutomaticZenRule}, 769 * a {@code null} value here means the previous set of effects is retained. 770 */ 771 @NonNull setDeviceEffects(@ullable ZenDeviceEffects deviceEffects)772 public Builder setDeviceEffects(@Nullable ZenDeviceEffects deviceEffects) { 773 mDeviceEffects = deviceEffects; 774 return this; 775 } 776 777 /** 778 * Sets the type of the rule. 779 */ setType(@ype int type)780 public @NonNull Builder setType(@Type int type) { 781 mType = checkValidType(type); 782 return this; 783 } 784 785 /** 786 * Sets a user visible description of when this rule will be active 787 * (see {@link Condition#STATE_TRUE}). 788 * 789 * <p>A description should be a (localized) string like "Mon-Fri, 9pm-7am" or 790 * "When connected to [Car Name]". 791 */ setTriggerDescription(@ullable String description)792 public @NonNull Builder setTriggerDescription(@Nullable String description) { 793 mDescription = description; 794 return this; 795 } 796 797 /** 798 * Sets a resource id of a tintable vector drawable representing the rule in image form. 799 */ setIconResId(@rawableRes int iconResId)800 public @NonNull Builder setIconResId(@DrawableRes int iconResId) { 801 mIconResId = iconResId; 802 return this; 803 } 804 805 /** 806 * Sets whether this rule can be manually activated by the user even when the triggering 807 * condition for the rule is not met. 808 */ setManualInvocationAllowed(boolean allowManualInvocation)809 public @NonNull Builder setManualInvocationAllowed(boolean allowManualInvocation) { 810 mAllowManualInvocation = allowManualInvocation; 811 return this; 812 } 813 814 /** 815 * Sets the time at which this rule was created, in milliseconds since epoch 816 * @hide 817 */ setCreationTime(long creationTime)818 public @NonNull Builder setCreationTime(long creationTime) { 819 mCreationTime = creationTime; 820 return this; 821 } 822 823 /** 824 * Sets the package that owns this rule 825 * @hide 826 */ setPackage(@onNull String pkg)827 public @NonNull Builder setPackage(@NonNull String pkg) { 828 mPkg = pkg; 829 return this; 830 } 831 build()832 public @NonNull AutomaticZenRule build() { 833 AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConfigurationActivity, 834 mConditionId, mPolicy, mInterruptionFilter, mEnabled); 835 rule.mDeviceEffects = mDeviceEffects; 836 rule.creationTime = mCreationTime; 837 rule.mType = mType; 838 rule.mTriggerDescription = mDescription; 839 rule.mIconResId = mIconResId; 840 rule.mAllowManualInvocation = mAllowManualInvocation; 841 rule.setPackageName(mPkg); 842 843 return rule; 844 } 845 } 846 847 /** @hide */ 848 public static final class AzrWithId implements Parcelable { 849 public final String mId; 850 public final AutomaticZenRule mRule; 851 AzrWithId(String id, AutomaticZenRule rule)852 public AzrWithId(String id, AutomaticZenRule rule) { 853 mId = id; 854 mRule = rule; 855 } 856 857 public static final Creator<AzrWithId> CREATOR = new Creator<>() { 858 @Override 859 public AzrWithId createFromParcel(Parcel in) { 860 return new AzrWithId( 861 in.readString8(), 862 in.readParcelable(AutomaticZenRule.class.getClassLoader(), 863 AutomaticZenRule.class)); 864 } 865 866 @Override 867 public AzrWithId[] newArray(int size) { 868 return new AzrWithId[size]; 869 } 870 }; 871 872 @Override writeToParcel(@onNull Parcel dest, int flags)873 public void writeToParcel(@NonNull Parcel dest, int flags) { 874 dest.writeString8(mId); 875 dest.writeParcelable(mRule, flags); 876 } 877 878 @Override describeContents()879 public int describeContents() { 880 return 0; 881 } 882 } 883 } 884