Files
rr3-apk/decompiled-community/sources/androidx/work/impl/background/systemjob/SystemJobScheduler.java
Daniel Elliott c080f0d97f Add Discord community version (64-bit only)
- Added realracing3-community.apk (71.57 MB)
- Removed 32-bit support (armeabi-v7a)
- Only includes arm64-v8a libraries
- Decompiled source code included
- Added README-community.md with analysis
2026-02-18 15:48:36 -08:00

251 lines
11 KiB
Java

package androidx.work.impl.background.systemjob;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.os.PersistableBundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.core.util.Consumer;
import androidx.work.Configuration;
import androidx.work.Logger;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkInfo;
import androidx.work.impl.Scheduler;
import androidx.work.impl.WorkDatabase;
import androidx.work.impl.model.SystemIdInfo;
import androidx.work.impl.model.SystemIdInfoKt;
import androidx.work.impl.model.WorkGenerationalId;
import androidx.work.impl.model.WorkSpec;
import androidx.work.impl.model.WorkSpecDao;
import androidx.work.impl.model.WorkSpecKt;
import androidx.work.impl.utils.IdGenerator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@RequiresApi(23)
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP})
/* loaded from: classes.dex */
public class SystemJobScheduler implements Scheduler {
private static final String TAG = Logger.tagWithPrefix("SystemJobScheduler");
private final Configuration mConfiguration;
private final Context mContext;
private final JobScheduler mJobScheduler;
private final SystemJobInfoConverter mSystemJobInfoConverter;
private final WorkDatabase mWorkDatabase;
@Override // androidx.work.impl.Scheduler
public boolean hasLimitedSchedulingSlots() {
return true;
}
public SystemJobScheduler(@NonNull Context context, @NonNull WorkDatabase workDatabase, @NonNull Configuration configuration) {
this(context, workDatabase, configuration, JobSchedulerExtKt.getWmJobScheduler(context), new SystemJobInfoConverter(context, configuration.getClock(), configuration.isMarkingJobsAsImportantWhileForeground()));
}
@VisibleForTesting
public SystemJobScheduler(@NonNull Context context, @NonNull WorkDatabase workDatabase, @NonNull Configuration configuration, @NonNull JobScheduler jobScheduler, @NonNull SystemJobInfoConverter systemJobInfoConverter) {
this.mContext = context;
this.mJobScheduler = jobScheduler;
this.mSystemJobInfoConverter = systemJobInfoConverter;
this.mWorkDatabase = workDatabase;
this.mConfiguration = configuration;
}
@Override // androidx.work.impl.Scheduler
public void schedule(@NonNull WorkSpec... workSpecArr) {
IdGenerator idGenerator = new IdGenerator(this.mWorkDatabase);
for (WorkSpec workSpec : workSpecArr) {
this.mWorkDatabase.beginTransaction();
try {
WorkSpec workSpec2 = this.mWorkDatabase.workSpecDao().getWorkSpec(workSpec.id);
if (workSpec2 == null) {
Logger.get().warning(TAG, "Skipping scheduling " + workSpec.id + " because it's no longer in the DB");
this.mWorkDatabase.setTransactionSuccessful();
} else if (workSpec2.state != WorkInfo.State.ENQUEUED) {
Logger.get().warning(TAG, "Skipping scheduling " + workSpec.id + " because it is no longer enqueued");
this.mWorkDatabase.setTransactionSuccessful();
} else {
WorkGenerationalId generationalId = WorkSpecKt.generationalId(workSpec);
SystemIdInfo systemIdInfo = this.mWorkDatabase.systemIdInfoDao().getSystemIdInfo(generationalId);
int nextJobSchedulerIdWithRange = systemIdInfo != null ? systemIdInfo.systemId : idGenerator.nextJobSchedulerIdWithRange(this.mConfiguration.getMinJobSchedulerId(), this.mConfiguration.getMaxJobSchedulerId());
if (systemIdInfo == null) {
this.mWorkDatabase.systemIdInfoDao().insertSystemIdInfo(SystemIdInfoKt.systemIdInfo(generationalId, nextJobSchedulerIdWithRange));
}
scheduleInternal(workSpec, nextJobSchedulerIdWithRange);
this.mWorkDatabase.setTransactionSuccessful();
}
} finally {
this.mWorkDatabase.endTransaction();
}
}
}
@VisibleForTesting
public void scheduleInternal(@NonNull WorkSpec workSpec, int i) {
JobInfo convert = this.mSystemJobInfoConverter.convert(workSpec, i);
Logger logger = Logger.get();
String str = TAG;
logger.debug(str, "Scheduling work ID " + workSpec.id + "Job ID " + i);
try {
if (this.mJobScheduler.schedule(convert) == 0) {
Logger.get().warning(str, "Unable to schedule work ID " + workSpec.id);
if (workSpec.expedited && workSpec.outOfQuotaPolicy == OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) {
workSpec.expedited = false;
Logger.get().debug(str, String.format("Scheduling a non-expedited job (work ID %s)", workSpec.id));
scheduleInternal(workSpec, i);
}
}
} catch (IllegalStateException e) {
String createErrorMessage = JobSchedulerExtKt.createErrorMessage(this.mContext, this.mWorkDatabase, this.mConfiguration);
Logger.get().error(TAG, createErrorMessage);
IllegalStateException illegalStateException = new IllegalStateException(createErrorMessage, e);
Consumer<Throwable> schedulingExceptionHandler = this.mConfiguration.getSchedulingExceptionHandler();
if (schedulingExceptionHandler != null) {
schedulingExceptionHandler.accept(illegalStateException);
return;
}
throw illegalStateException;
} catch (Throwable th) {
Logger.get().error(TAG, "Unable to schedule " + workSpec, th);
}
}
@Override // androidx.work.impl.Scheduler
public void cancel(@NonNull String str) {
List<Integer> pendingJobIds = getPendingJobIds(this.mContext, this.mJobScheduler, str);
if (pendingJobIds == null || pendingJobIds.isEmpty()) {
return;
}
Iterator<Integer> it = pendingJobIds.iterator();
while (it.hasNext()) {
cancelJobById(this.mJobScheduler, it.next().intValue());
}
this.mWorkDatabase.systemIdInfoDao().removeSystemIdInfo(str);
}
private static void cancelJobById(@NonNull JobScheduler jobScheduler, int i) {
try {
jobScheduler.cancel(i);
} catch (Throwable th) {
Logger.get().error(TAG, String.format(Locale.getDefault(), "Exception while trying to cancel job (%d)", Integer.valueOf(i)), th);
}
}
public static void cancelAllInAllNamespaces(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= 34) {
JobSchedulerExtKt.getWmJobScheduler(context).cancelAll();
}
JobScheduler jobScheduler = (JobScheduler) context.getSystemService("jobscheduler");
List<JobInfo> pendingJobs = getPendingJobs(context, jobScheduler);
if (pendingJobs == null || pendingJobs.isEmpty()) {
return;
}
Iterator<JobInfo> it = pendingJobs.iterator();
while (it.hasNext()) {
cancelJobById(jobScheduler, it.next().getId());
}
}
public static boolean reconcileJobs(@NonNull Context context, @NonNull WorkDatabase workDatabase) {
JobScheduler wmJobScheduler = JobSchedulerExtKt.getWmJobScheduler(context);
List<JobInfo> pendingJobs = getPendingJobs(context, wmJobScheduler);
List<String> workSpecIds = workDatabase.systemIdInfoDao().getWorkSpecIds();
boolean z = false;
HashSet hashSet = new HashSet(pendingJobs != null ? pendingJobs.size() : 0);
if (pendingJobs != null && !pendingJobs.isEmpty()) {
for (JobInfo jobInfo : pendingJobs) {
WorkGenerationalId workGenerationalIdFromJobInfo = getWorkGenerationalIdFromJobInfo(jobInfo);
if (workGenerationalIdFromJobInfo != null) {
hashSet.add(workGenerationalIdFromJobInfo.getWorkSpecId());
} else {
cancelJobById(wmJobScheduler, jobInfo.getId());
}
}
}
Iterator<String> it = workSpecIds.iterator();
while (true) {
if (!it.hasNext()) {
break;
}
if (!hashSet.contains(it.next())) {
Logger.get().debug(TAG, "Reconciling jobs");
z = true;
break;
}
}
if (z) {
workDatabase.beginTransaction();
try {
WorkSpecDao workSpecDao = workDatabase.workSpecDao();
Iterator<String> it2 = workSpecIds.iterator();
while (it2.hasNext()) {
workSpecDao.markWorkSpecScheduled(it2.next(), -1L);
}
workDatabase.setTransactionSuccessful();
workDatabase.endTransaction();
} catch (Throwable th) {
workDatabase.endTransaction();
throw th;
}
}
return z;
}
@Nullable
public static List<JobInfo> getPendingJobs(@NonNull Context context, @NonNull JobScheduler jobScheduler) {
List<JobInfo> safePendingJobs = JobSchedulerExtKt.getSafePendingJobs(jobScheduler);
if (safePendingJobs == null) {
return null;
}
ArrayList arrayList = new ArrayList(safePendingJobs.size());
ComponentName componentName = new ComponentName(context, (Class<?>) SystemJobService.class);
for (JobInfo jobInfo : safePendingJobs) {
if (componentName.equals(jobInfo.getService())) {
arrayList.add(jobInfo);
}
}
return arrayList;
}
@Nullable
private static List<Integer> getPendingJobIds(@NonNull Context context, @NonNull JobScheduler jobScheduler, @NonNull String str) {
List<JobInfo> pendingJobs = getPendingJobs(context, jobScheduler);
if (pendingJobs == null) {
return null;
}
ArrayList arrayList = new ArrayList(2);
for (JobInfo jobInfo : pendingJobs) {
WorkGenerationalId workGenerationalIdFromJobInfo = getWorkGenerationalIdFromJobInfo(jobInfo);
if (workGenerationalIdFromJobInfo != null && str.equals(workGenerationalIdFromJobInfo.getWorkSpecId())) {
arrayList.add(Integer.valueOf(jobInfo.getId()));
}
}
return arrayList;
}
@Nullable
private static WorkGenerationalId getWorkGenerationalIdFromJobInfo(@NonNull JobInfo jobInfo) {
PersistableBundle extras = jobInfo.getExtras();
if (extras == null) {
return null;
}
try {
if (!extras.containsKey("EXTRA_WORK_SPEC_ID")) {
return null;
}
return new WorkGenerationalId(extras.getString("EXTRA_WORK_SPEC_ID"), extras.getInt("EXTRA_WORK_SPEC_GENERATION", 0));
} catch (NullPointerException unused) {
return null;
}
}
}