1 /* 2 * Copyright (C) 2024 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.adservices.shared.spe.scheduling; 18 19 import android.annotation.Nullable; 20 import android.app.job.JobInfo; 21 import android.os.PersistableBundle; 22 23 import com.android.adservices.shared.proto.JobPolicy; 24 25 import java.util.Objects; 26 27 /** 28 * This class stores the specifications used to schedule a job using {@link PolicyJobScheduler}, 29 * which is a part of SPE (Scheduling Policy Engine) framework. 30 * 31 * <p>An instance of {@link JobSpec} needed to be passed into {@link PolicyJobScheduler} with a job 32 * ID and {@link JobPolicy} at least. And by default, a {@link JobSpec} is created with a default 33 * {@link BackoffPolicy}. 34 */ 35 public final class JobSpec { 36 private final JobPolicy mJobPolicy; 37 private final BackoffPolicy mBackoffPolicy; 38 private final PersistableBundle mExtras; 39 private final boolean mShouldForceSchedule; 40 JobSpec( JobPolicy jobPolicy, @Nullable BackoffPolicy backoffPolicy, @Nullable PersistableBundle extras, boolean shouldForceSchedule)41 private JobSpec( 42 JobPolicy jobPolicy, 43 @Nullable BackoffPolicy backoffPolicy, 44 @Nullable PersistableBundle extras, 45 boolean shouldForceSchedule) { 46 mJobPolicy = Objects.requireNonNull(jobPolicy); 47 mBackoffPolicy = backoffPolicy == null ? BackoffPolicy.DEFAULT : backoffPolicy; 48 mExtras = extras; 49 mShouldForceSchedule = shouldForceSchedule; 50 } 51 52 /** Returns a {@link JobPolicy} used for the default constraints to schedule a job. */ getJobPolicy()53 public JobPolicy getJobPolicy() { 54 return mJobPolicy; 55 } 56 57 /** 58 * Returns a {@link BackoffPolicy} to schedule a job. See {@link JobInfo#getBackoffPolicy()} for 59 * more details. 60 */ getBackoffPolicy()61 public BackoffPolicy getBackoffPolicy() { 62 return mBackoffPolicy; 63 } 64 65 /** 66 * Returns a {@link PersistableBundle} to contain any data that's used for communications 67 * between job scheduling and execution. See {@link JobInfo#getExtras()} for more details. 68 */ 69 @Nullable getExtras()70 public PersistableBundle getExtras() { 71 return mExtras; 72 } 73 74 /** 75 * Returns a {@link Boolean} to indicate if the job will be scheduled even with a same {@link 76 * JobInfo}. 77 */ getShouldForceSchedule()78 public boolean getShouldForceSchedule() { 79 return mShouldForceSchedule; 80 } 81 82 @Override equals(Object o)83 public boolean equals(Object o) { 84 if (this == o) { 85 return true; 86 } 87 if (!(o instanceof JobSpec that)) { 88 return false; 89 } 90 91 // There is no public method to compare to PersistableBundle. Ignore the difference on it 92 // for the reasons 1) only a few jobs will use this extra field. 2) this equals() method for 93 // JobSpec is not used in Production. 94 return mJobPolicy.equals(that.mJobPolicy) 95 && mBackoffPolicy.equals(that.mBackoffPolicy) 96 && mShouldForceSchedule == that.mShouldForceSchedule; 97 } 98 99 @Override hashCode()100 public int hashCode() { 101 return Objects.hash(mJobPolicy, mBackoffPolicy, mShouldForceSchedule); 102 } 103 104 @Override toString()105 public String toString() { 106 return "JobSpec{" 107 + "mBackoffPolicy=" 108 + mBackoffPolicy 109 + ", mExtras=" 110 + mExtras 111 + ", mShouldForceSchedule=" 112 + mShouldForceSchedule 113 + '}'; 114 } 115 116 /** Builder class for {@link JobSpec}. */ 117 public static final class Builder { 118 private final JobPolicy mJobPolicy; 119 @Nullable private BackoffPolicy mBackoffPolicy; 120 @Nullable private PersistableBundle mExtras; 121 // By default, the job should not force to schedule with same info. 122 private boolean mShouldForceSchedule; 123 124 /** 125 * Constructor. 126 * 127 * @param jobPolicy the {@link JobPolicy} of the job to schedule. 128 * @throws IllegalArgumentException if the {@code jobPolicy} doesn't configure a job ID. 129 */ Builder(JobPolicy jobPolicy)130 public Builder(JobPolicy jobPolicy) { 131 mJobPolicy = Objects.requireNonNull(jobPolicy); 132 133 if (!mJobPolicy.hasJobId()) { 134 throw new IllegalArgumentException("JobPolicy must configure the job ID!"); 135 } 136 } 137 138 /** 139 * Setter for {@link #getBackoffPolicy()}. 140 * 141 * <p>By default, {@link #mBackoffPolicy} uses {@link BackoffPolicy#DEFAULT} if it's not 142 * set. 143 */ setBackoffPolicy(@ullable BackoffPolicy value)144 public Builder setBackoffPolicy(@Nullable BackoffPolicy value) { 145 mBackoffPolicy = value; 146 return this; 147 } 148 149 /** Setter for {@link #getExtras()}. */ setExtras(@ullable PersistableBundle value)150 public Builder setExtras(@Nullable PersistableBundle value) { 151 mExtras = value; 152 return this; 153 } 154 155 /** Setter for {@link #getShouldForceSchedule()}. */ setShouldForceSchedule(boolean value)156 public Builder setShouldForceSchedule(boolean value) { 157 mShouldForceSchedule = value; 158 return this; 159 } 160 161 /** Build an instance of {@link JobSpec}. */ build()162 public JobSpec build() { 163 return new JobSpec(mJobPolicy, mBackoffPolicy, mExtras, mShouldForceSchedule); 164 } 165 } 166 } 167