1 /* 2 * Copyright 2018 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 androidx.work; 18 19 import android.arch.persistence.room.ColumnInfo; 20 import android.net.Uri; 21 import android.os.Build; 22 import android.support.annotation.NonNull; 23 import android.support.annotation.RequiresApi; 24 25 /** 26 * The constraints that can be applied to one {@link WorkRequest}. 27 */ 28 public final class Constraints { 29 30 public static final Constraints NONE = new Constraints.Builder().build(); 31 32 @ColumnInfo(name = "required_network_type") 33 NetworkType mRequiredNetworkType; 34 35 @ColumnInfo(name = "requires_charging") 36 boolean mRequiresCharging; 37 38 @ColumnInfo(name = "requires_device_idle") 39 boolean mRequiresDeviceIdle; 40 41 @ColumnInfo(name = "requires_battery_not_low") 42 boolean mRequiresBatteryNotLow; 43 44 @ColumnInfo(name = "requires_storage_not_low") 45 boolean mRequiresStorageNotLow; 46 47 @ColumnInfo(name = "content_uri_triggers") 48 ContentUriTriggers mContentUriTriggers; 49 Constraints()50 public Constraints() { // stub required for room 51 } 52 Constraints(Builder builder)53 private Constraints(Builder builder) { 54 mRequiresCharging = builder.mRequiresCharging; 55 mRequiresDeviceIdle = Build.VERSION.SDK_INT >= 23 && builder.mRequiresDeviceIdle; 56 mRequiredNetworkType = builder.mRequiredNetworkType; 57 mRequiresBatteryNotLow = builder.mRequiresBatteryNotLow; 58 mRequiresStorageNotLow = builder.mRequiresStorageNotLow; 59 mContentUriTriggers = (Build.VERSION.SDK_INT >= 24) 60 ? builder.mContentUriTriggers 61 : new ContentUriTriggers(); 62 } 63 getRequiredNetworkType()64 public @NonNull NetworkType getRequiredNetworkType() { 65 return mRequiredNetworkType; 66 } 67 setRequiredNetworkType(@onNull NetworkType requiredNetworkType)68 public void setRequiredNetworkType(@NonNull NetworkType requiredNetworkType) { 69 mRequiredNetworkType = requiredNetworkType; 70 } 71 72 /** 73 * @return If the constraints require charging. 74 */ requiresCharging()75 public boolean requiresCharging() { 76 return mRequiresCharging; 77 } 78 setRequiresCharging(boolean requiresCharging)79 public void setRequiresCharging(boolean requiresCharging) { 80 mRequiresCharging = requiresCharging; 81 } 82 83 /** 84 * @return If the constraints require device idle. 85 */ 86 @RequiresApi(23) requiresDeviceIdle()87 public boolean requiresDeviceIdle() { 88 return mRequiresDeviceIdle; 89 } 90 91 @RequiresApi(23) setRequiresDeviceIdle(boolean requiresDeviceIdle)92 public void setRequiresDeviceIdle(boolean requiresDeviceIdle) { 93 mRequiresDeviceIdle = requiresDeviceIdle; 94 } 95 96 /** 97 * @return If the constraints require battery not low status. 98 */ requiresBatteryNotLow()99 public boolean requiresBatteryNotLow() { 100 return mRequiresBatteryNotLow; 101 } 102 setRequiresBatteryNotLow(boolean requiresBatteryNotLow)103 public void setRequiresBatteryNotLow(boolean requiresBatteryNotLow) { 104 mRequiresBatteryNotLow = requiresBatteryNotLow; 105 } 106 107 /** 108 * @return If the constraints require storage not low status. 109 */ requiresStorageNotLow()110 public boolean requiresStorageNotLow() { 111 return mRequiresStorageNotLow; 112 } 113 setRequiresStorageNotLow(boolean requiresStorageNotLow)114 public void setRequiresStorageNotLow(boolean requiresStorageNotLow) { 115 mRequiresStorageNotLow = requiresStorageNotLow; 116 } 117 118 @RequiresApi(24) setContentUriTriggers(ContentUriTriggers mContentUriTriggers)119 public void setContentUriTriggers(ContentUriTriggers mContentUriTriggers) { 120 this.mContentUriTriggers = mContentUriTriggers; 121 } 122 123 @RequiresApi(24) getContentUriTriggers()124 public ContentUriTriggers getContentUriTriggers() { 125 return mContentUriTriggers; 126 } 127 128 /** 129 * @return {@code true} if {@link ContentUriTriggers} is not empty 130 */ 131 @RequiresApi(24) hasContentUriTriggers()132 public boolean hasContentUriTriggers() { 133 return mContentUriTriggers.size() > 0; 134 } 135 136 @Override equals(Object o)137 public boolean equals(Object o) { 138 if (this == o) { 139 return true; 140 } 141 if (o == null || getClass() != o.getClass()) { 142 return false; 143 } 144 Constraints other = (Constraints) o; 145 return mRequiredNetworkType == other.mRequiredNetworkType 146 && mRequiresCharging == other.mRequiresCharging 147 && mRequiresDeviceIdle == other.mRequiresDeviceIdle 148 && mRequiresBatteryNotLow == other.mRequiresBatteryNotLow 149 && mRequiresStorageNotLow == other.mRequiresStorageNotLow 150 && (mContentUriTriggers != null ? mContentUriTriggers.equals( 151 other.mContentUriTriggers) : other.mContentUriTriggers == null); 152 } 153 154 @Override hashCode()155 public int hashCode() { 156 int result = mRequiredNetworkType.hashCode(); 157 result = 31 * result + (mRequiresCharging ? 1 : 0); 158 result = 31 * result + (mRequiresDeviceIdle ? 1 : 0); 159 result = 31 * result + (mRequiresBatteryNotLow ? 1 : 0); 160 result = 31 * result + (mRequiresStorageNotLow ? 1 : 0); 161 result = 31 * result + (mContentUriTriggers != null ? mContentUriTriggers.hashCode() : 0); 162 return result; 163 } 164 165 /** 166 * Builder for {@link Constraints} class. 167 */ 168 public static final class Builder { 169 private boolean mRequiresCharging = false; 170 private boolean mRequiresDeviceIdle = false; 171 private NetworkType mRequiredNetworkType = NetworkType.NOT_REQUIRED; 172 private boolean mRequiresBatteryNotLow = false; 173 private boolean mRequiresStorageNotLow = false; 174 private ContentUriTriggers mContentUriTriggers = new ContentUriTriggers(); 175 176 /** 177 * Specify whether device should be plugged in for {@link WorkRequest} to run. 178 * Default is false. 179 * 180 * @param requiresCharging true if device must be plugged in, false otherwise 181 * @return current builder 182 */ setRequiresCharging(boolean requiresCharging)183 public Builder setRequiresCharging(boolean requiresCharging) { 184 this.mRequiresCharging = requiresCharging; 185 return this; 186 } 187 188 /** 189 * Specify whether device should be idle for {@link WorkRequest} to run. Default is 190 * false. 191 * 192 * @param requiresDeviceIdle true if device must be idle, false otherwise 193 * @return current builder 194 */ 195 @RequiresApi(23) setRequiresDeviceIdle(boolean requiresDeviceIdle)196 public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) { 197 this.mRequiresDeviceIdle = requiresDeviceIdle; 198 return this; 199 } 200 201 /** 202 * Specify whether device should have a particular {@link NetworkType} for 203 * {@link WorkRequest} to run. Default is {@link NetworkType#NOT_REQUIRED}. 204 * 205 * @param networkType type of network required 206 * @return current builder 207 */ setRequiredNetworkType(@onNull NetworkType networkType)208 public Builder setRequiredNetworkType(@NonNull NetworkType networkType) { 209 this.mRequiredNetworkType = networkType; 210 return this; 211 } 212 213 /** 214 * Specify whether device battery should not be below critical threshold for 215 * {@link WorkRequest} to run. Default is false. 216 * 217 * @param requiresBatteryNotLow true if battery should not be below critical threshold, 218 * false otherwise 219 * @return current builder 220 */ setRequiresBatteryNotLow(boolean requiresBatteryNotLow)221 public Builder setRequiresBatteryNotLow(boolean requiresBatteryNotLow) { 222 this.mRequiresBatteryNotLow = requiresBatteryNotLow; 223 return this; 224 } 225 226 /** 227 * Specify whether device available storage should not be below critical threshold for 228 * {@link WorkRequest} to run. Default is {@code false}. 229 * 230 * @param requiresStorageNotLow true if available storage should not be below critical 231 * threshold, false otherwise 232 * @return current builder 233 */ setRequiresStorageNotLow(boolean requiresStorageNotLow)234 public Builder setRequiresStorageNotLow(boolean requiresStorageNotLow) { 235 this.mRequiresStorageNotLow = requiresStorageNotLow; 236 return this; 237 } 238 239 /** 240 * Specify whether {@link WorkRequest} should run when a content {@link android.net.Uri} 241 * is updated. This method requires API 24 or higher. 242 * 243 * @param uri {@link android.net.Uri} to observe 244 * @param triggerForDescendants {@code true} if any changes in descendants cause this 245 * {@link WorkRequest} to run 246 * @return The current {@link Builder} 247 */ 248 @RequiresApi(24) addContentUriTrigger(Uri uri, boolean triggerForDescendants)249 public Builder addContentUriTrigger(Uri uri, boolean triggerForDescendants) { 250 mContentUriTriggers.add(uri, triggerForDescendants); 251 return this; 252 } 253 254 /** 255 * Generates the {@link Constraints} from this Builder. 256 * 257 * @return new {@link Constraints} which can be attached to a {@link WorkRequest} 258 */ build()259 public Constraints build() { 260 return new Constraints(this); 261 } 262 } 263 } 264