1 /* 2 * Copyright (C) 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 com.google.android.startop.iorap; 18 19 import android.app.job.JobParameters; 20 import android.annotation.NonNull; 21 import android.os.Parcelable; 22 import android.os.Parcel; 23 24 import android.annotation.IntDef; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 29 /** 30 * Forward JobService events to iorapd. <br /><br /> 31 * 32 * iorapd sometimes need to use background jobs. Forwarding these events to iorapd 33 * notifies iorapd when it is an opportune time to execute these background jobs. 34 * 35 * @hide 36 */ 37 public class JobScheduledEvent implements Parcelable { 38 39 /** JobService#onJobStarted */ 40 public static final int TYPE_START_JOB = 0; 41 /** JobService#onJobStopped */ 42 public static final int TYPE_STOP_JOB = 1; 43 private static final int TYPE_MAX = 1; 44 45 /** @hide */ 46 @IntDef(flag = true, prefix = { "TYPE_" }, value = { 47 TYPE_START_JOB, 48 TYPE_STOP_JOB, 49 }) 50 @Retention(RetentionPolicy.SOURCE) 51 public @interface Type {} 52 53 @Type public final int type; 54 55 /** @see JobParameters#getJobId() */ 56 public final int jobId; 57 58 public final String packageName; 59 60 public final boolean shouldUpdateVersions; 61 62 /** Device is 'idle' and it's charging (plugged in). */ 63 public static final int SORT_IDLE_MAINTENANCE = 0; 64 private static final int SORT_MAX = 0; 65 66 /** @hide */ 67 @IntDef(flag = true, prefix = { "SORT_" }, value = { 68 SORT_IDLE_MAINTENANCE, 69 }) 70 @Retention(RetentionPolicy.SOURCE) 71 public @interface Sort {} 72 73 /** 74 * Roughly corresponds to the {@code extras} fields in a JobParameters. 75 */ 76 @Sort public final int sort; 77 78 /** 79 * Creates a {@link #SORT_IDLE_MAINTENANCE} event from the type and job parameters. 80 * 81 * Only the job ID is retained from {@code jobParams}, all other param info is dropped. 82 */ 83 @NonNull createIdleMaintenance( @ype int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions)84 public static JobScheduledEvent createIdleMaintenance( 85 @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) { 86 return new JobScheduledEvent( 87 type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions); 88 } 89 JobScheduledEvent(@ype int type, int jobId, @Sort int sort, String packageName, boolean shouldUpdateVersions)90 private JobScheduledEvent(@Type int type, 91 int jobId, 92 @Sort int sort, 93 String packageName, 94 boolean shouldUpdateVersions) { 95 this.type = type; 96 this.jobId = jobId; 97 this.sort = sort; 98 this.packageName = packageName; 99 this.shouldUpdateVersions = shouldUpdateVersions; 100 101 checkConstructorArguments(); 102 } 103 checkConstructorArguments()104 private void checkConstructorArguments() { 105 CheckHelpers.checkTypeInRange(type, TYPE_MAX); 106 // No check for 'jobId': any int is valid. 107 CheckHelpers.checkTypeInRange(sort, SORT_MAX); 108 } 109 110 @Override equals(Object other)111 public boolean equals(Object other) { 112 if (this == other) { 113 return true; 114 } else if (other instanceof JobScheduledEvent) { 115 return equals((JobScheduledEvent) other); 116 } 117 return false; 118 } 119 equals(JobScheduledEvent other)120 private boolean equals(JobScheduledEvent other) { 121 return type == other.type && 122 jobId == other.jobId && 123 sort == other.sort && 124 packageName.equals(other.packageName) && 125 shouldUpdateVersions == other.shouldUpdateVersions; 126 } 127 128 @Override toString()129 public String toString() { 130 return String.format( 131 "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}", 132 type, jobId, sort, packageName, shouldUpdateVersions); 133 } 134 135 //<editor-fold desc="Binder boilerplate"> 136 @Override writeToParcel(Parcel out, int flags)137 public void writeToParcel(Parcel out, int flags) { 138 out.writeInt(type); 139 out.writeInt(jobId); 140 out.writeInt(sort); 141 out.writeString(packageName); 142 out.writeBoolean(shouldUpdateVersions); 143 144 // We do not parcel the entire JobParameters here because there is no C++ equivalent 145 // of that class [which the iorapd side of the binder interface requires]. 146 } 147 JobScheduledEvent(Parcel in)148 private JobScheduledEvent(Parcel in) { 149 this.type = in.readInt(); 150 this.jobId = in.readInt(); 151 this.sort = in.readInt(); 152 this.packageName = in.readString(); 153 this.shouldUpdateVersions = in.readBoolean(); 154 155 checkConstructorArguments(); 156 } 157 158 @Override describeContents()159 public int describeContents() { 160 return 0; 161 } 162 163 public static final Parcelable.Creator<JobScheduledEvent> CREATOR 164 = new Parcelable.Creator<JobScheduledEvent>() { 165 public JobScheduledEvent createFromParcel(Parcel in) { 166 return new JobScheduledEvent(in); 167 } 168 169 public JobScheduledEvent[] newArray(int size) { 170 return new JobScheduledEvent[size]; 171 } 172 }; 173 //</editor-fold> 174 } 175