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 android.service.notification; 18 19 import android.annotation.IntDef; 20 import android.content.Context; 21 import android.net.Uri; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.util.proto.ProtoOutputStream; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * The current condition of an {@link android.app.AutomaticZenRule}, provided by the 32 * app that owns the rule. Used to tell the system to enter Do Not 33 * Disturb mode and request that the system exit Do Not Disturb mode. 34 */ 35 public final class Condition implements Parcelable { 36 37 public static final String SCHEME = "condition"; 38 39 /** @hide */ 40 @IntDef(prefix = { "STATE_" }, value = { 41 STATE_FALSE, 42 STATE_TRUE, 43 STATE_UNKNOWN, 44 STATE_ERROR 45 }) 46 @Retention(RetentionPolicy.SOURCE) 47 public @interface State {} 48 49 /** 50 * Indicates that Do Not Disturb should be turned off. Note that all Conditions from all 51 * {@link android.app.AutomaticZenRule} providers must be off for Do Not Disturb to be turned 52 * off on the device. 53 */ 54 public static final int STATE_FALSE = 0; 55 /** 56 * Indicates that Do Not Disturb should be turned on. 57 */ 58 public static final int STATE_TRUE = 1; 59 60 public static final int STATE_UNKNOWN = 2; 61 public static final int STATE_ERROR = 3; 62 63 public static final int FLAG_RELEVANT_NOW = 1 << 0; 64 public static final int FLAG_RELEVANT_ALWAYS = 1 << 1; 65 66 /** 67 * The URI representing the rule being updated. 68 * See {@link android.app.AutomaticZenRule#getConditionId()}. 69 */ 70 public final Uri id; 71 72 /** 73 * A summary of what the rule encoded in {@link #id} means when it is enabled. User visible 74 * if the state of the condition is {@link #STATE_TRUE}. 75 */ 76 public final String summary; 77 78 public final String line1; 79 public final String line2; 80 81 /** 82 * The state of this condition. {@link #STATE_TRUE} will enable Do Not Disturb mode. 83 * {@link #STATE_FALSE} will turn Do Not Disturb off for this rule. Note that Do Not Disturb 84 * might still be enabled globally if other conditions are in a {@link #STATE_TRUE} state. 85 */ 86 @State 87 public final int state; 88 89 public final int flags; 90 public final int icon; 91 92 /** 93 * An object representing the current state of a {@link android.app.AutomaticZenRule}. 94 * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule 95 * @param summary a user visible description of the rule state. 96 */ Condition(Uri id, String summary, int state)97 public Condition(Uri id, String summary, int state) { 98 this(id, summary, "", "", -1, state, FLAG_RELEVANT_ALWAYS); 99 } 100 Condition(Uri id, String summary, String line1, String line2, int icon, int state, int flags)101 public Condition(Uri id, String summary, String line1, String line2, int icon, 102 int state, int flags) { 103 if (id == null) throw new IllegalArgumentException("id is required"); 104 if (summary == null) throw new IllegalArgumentException("summary is required"); 105 if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state); 106 this.id = id; 107 this.summary = summary; 108 this.line1 = line1; 109 this.line2 = line2; 110 this.icon = icon; 111 this.state = state; 112 this.flags = flags; 113 } 114 Condition(Parcel source)115 public Condition(Parcel source) { 116 this((Uri)source.readParcelable(Condition.class.getClassLoader()), 117 source.readString(), 118 source.readString(), 119 source.readString(), 120 source.readInt(), 121 source.readInt(), 122 source.readInt()); 123 } 124 isValidState(int state)125 private static boolean isValidState(int state) { 126 return state >= STATE_FALSE && state <= STATE_ERROR; 127 } 128 129 @Override writeToParcel(Parcel dest, int flags)130 public void writeToParcel(Parcel dest, int flags) { 131 dest.writeParcelable(id, 0); 132 dest.writeString(summary); 133 dest.writeString(line1); 134 dest.writeString(line2); 135 dest.writeInt(icon); 136 dest.writeInt(state); 137 dest.writeInt(this.flags); 138 } 139 140 @Override toString()141 public String toString() { 142 return new StringBuilder(Condition.class.getSimpleName()).append('[') 143 .append("state=").append(stateToString(state)) 144 .append(",id=").append(id) 145 .append(",summary=").append(summary) 146 .append(",line1=").append(line1) 147 .append(",line2=").append(line2) 148 .append(",icon=").append(icon) 149 .append(",flags=").append(flags) 150 .append(']').toString(); 151 } 152 153 /** @hide */ writeToProto(ProtoOutputStream proto, long fieldId)154 public void writeToProto(ProtoOutputStream proto, long fieldId) { 155 final long token = proto.start(fieldId); 156 157 // id is guaranteed not to be null. 158 proto.write(ConditionProto.ID, id.toString()); 159 proto.write(ConditionProto.SUMMARY, summary); 160 proto.write(ConditionProto.LINE_1, line1); 161 proto.write(ConditionProto.LINE_2, line2); 162 proto.write(ConditionProto.ICON, icon); 163 proto.write(ConditionProto.STATE, state); 164 proto.write(ConditionProto.FLAGS, flags); 165 166 proto.end(token); 167 } 168 stateToString(int state)169 public static String stateToString(int state) { 170 if (state == STATE_FALSE) return "STATE_FALSE"; 171 if (state == STATE_TRUE) return "STATE_TRUE"; 172 if (state == STATE_UNKNOWN) return "STATE_UNKNOWN"; 173 if (state == STATE_ERROR) return "STATE_ERROR"; 174 throw new IllegalArgumentException("state is invalid: " + state); 175 } 176 relevanceToString(int flags)177 public static String relevanceToString(int flags) { 178 final boolean now = (flags & FLAG_RELEVANT_NOW) != 0; 179 final boolean always = (flags & FLAG_RELEVANT_ALWAYS) != 0; 180 if (!now && !always) return "NONE"; 181 if (now && always) return "NOW, ALWAYS"; 182 return now ? "NOW" : "ALWAYS"; 183 } 184 185 @Override equals(Object o)186 public boolean equals(Object o) { 187 if (!(o instanceof Condition)) return false; 188 if (o == this) return true; 189 final Condition other = (Condition) o; 190 return Objects.equals(other.id, id) 191 && Objects.equals(other.summary, summary) 192 && Objects.equals(other.line1, line1) 193 && Objects.equals(other.line2, line2) 194 && other.icon == icon 195 && other.state == state 196 && other.flags == flags; 197 } 198 199 @Override hashCode()200 public int hashCode() { 201 return Objects.hash(id, summary, line1, line2, icon, state, flags); 202 } 203 204 @Override describeContents()205 public int describeContents() { 206 return 0; 207 } 208 copy()209 public Condition copy() { 210 final Parcel parcel = Parcel.obtain(); 211 try { 212 writeToParcel(parcel, 0); 213 parcel.setDataPosition(0); 214 return new Condition(parcel); 215 } finally { 216 parcel.recycle(); 217 } 218 } 219 newId(Context context)220 public static Uri.Builder newId(Context context) { 221 return new Uri.Builder() 222 .scheme(Condition.SCHEME) 223 .authority(context.getPackageName()); 224 } 225 isValidId(Uri id, String pkg)226 public static boolean isValidId(Uri id, String pkg) { 227 return id != null && SCHEME.equals(id.getScheme()) && pkg.equals(id.getAuthority()); 228 } 229 230 public static final @android.annotation.NonNull Parcelable.Creator<Condition> CREATOR 231 = new Parcelable.Creator<Condition>() { 232 @Override 233 public Condition createFromParcel(Parcel source) { 234 return new Condition(source); 235 } 236 237 @Override 238 public Condition[] newArray(int size) { 239 return new Condition[size]; 240 } 241 }; 242 } 243