Files
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

243 lines
11 KiB
Java

package androidx.work.impl.background.greedy;
import android.content.Context;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.work.Configuration;
import androidx.work.Constraints;
import androidx.work.Logger;
import androidx.work.RunnableScheduler;
import androidx.work.WorkInfo;
import androidx.work.WorkRequest;
import androidx.work.impl.ExecutionListener;
import androidx.work.impl.Processor;
import androidx.work.impl.Scheduler;
import androidx.work.impl.StartStopToken;
import androidx.work.impl.StartStopTokens;
import androidx.work.impl.WorkLauncher;
import androidx.work.impl.constraints.ConstraintsState;
import androidx.work.impl.constraints.OnConstraintsStateChangedListener;
import androidx.work.impl.constraints.WorkConstraintsTracker;
import androidx.work.impl.constraints.WorkConstraintsTrackerKt;
import androidx.work.impl.constraints.trackers.Trackers;
import androidx.work.impl.model.WorkGenerationalId;
import androidx.work.impl.model.WorkSpec;
import androidx.work.impl.model.WorkSpecKt;
import androidx.work.impl.utils.ProcessUtils;
import androidx.work.impl.utils.taskexecutor.TaskExecutor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import kotlinx.coroutines.Job;
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP})
/* loaded from: classes.dex */
public class GreedyScheduler implements Scheduler, OnConstraintsStateChangedListener, ExecutionListener {
private static final int NON_THROTTLE_RUN_ATTEMPT_COUNT = 5;
private static final String TAG = Logger.tagWithPrefix("GreedyScheduler");
private final Configuration mConfiguration;
private final WorkConstraintsTracker mConstraintsTracker;
private final Context mContext;
private DelayedWorkTracker mDelayedWorkTracker;
Boolean mInDefaultProcess;
private final Processor mProcessor;
private boolean mRegisteredExecutionListener;
private final TaskExecutor mTaskExecutor;
private final TimeLimiter mTimeLimiter;
private final WorkLauncher mWorkLauncher;
private final Map<WorkGenerationalId, Job> mConstrainedWorkSpecs = new HashMap();
private final Object mLock = new Object();
private final StartStopTokens mStartStopTokens = StartStopTokens.create();
private final Map<WorkGenerationalId, AttemptData> mFirstRunAttempts = new HashMap();
@Override // androidx.work.impl.Scheduler
public boolean hasLimitedSchedulingSlots() {
return false;
}
@VisibleForTesting
public void setDelayedWorkTracker(@NonNull DelayedWorkTracker delayedWorkTracker) {
this.mDelayedWorkTracker = delayedWorkTracker;
}
public GreedyScheduler(@NonNull Context context, @NonNull Configuration configuration, @NonNull Trackers trackers, @NonNull Processor processor, @NonNull WorkLauncher workLauncher, @NonNull TaskExecutor taskExecutor) {
this.mContext = context;
RunnableScheduler runnableScheduler = configuration.getRunnableScheduler();
this.mDelayedWorkTracker = new DelayedWorkTracker(this, runnableScheduler, configuration.getClock());
this.mTimeLimiter = new TimeLimiter(runnableScheduler, workLauncher);
this.mTaskExecutor = taskExecutor;
this.mConstraintsTracker = new WorkConstraintsTracker(trackers);
this.mConfiguration = configuration;
this.mProcessor = processor;
this.mWorkLauncher = workLauncher;
}
@Override // androidx.work.impl.Scheduler
public void schedule(@NonNull WorkSpec... workSpecArr) {
if (this.mInDefaultProcess == null) {
checkDefaultProcess();
}
if (!this.mInDefaultProcess.booleanValue()) {
Logger.get().info(TAG, "Ignoring schedule request in a secondary process");
return;
}
registerExecutionListenerIfNeeded();
HashSet<WorkSpec> hashSet = new HashSet();
HashSet hashSet2 = new HashSet();
for (WorkSpec workSpec : workSpecArr) {
if (!this.mStartStopTokens.contains(WorkSpecKt.generationalId(workSpec))) {
long max = Math.max(workSpec.calculateNextRunTime(), throttleIfNeeded(workSpec));
long currentTimeMillis = this.mConfiguration.getClock().currentTimeMillis();
if (workSpec.state == WorkInfo.State.ENQUEUED) {
if (currentTimeMillis < max) {
DelayedWorkTracker delayedWorkTracker = this.mDelayedWorkTracker;
if (delayedWorkTracker != null) {
delayedWorkTracker.schedule(workSpec, max);
}
} else if (workSpec.hasConstraints()) {
Constraints constraints = workSpec.constraints;
if (constraints.requiresDeviceIdle()) {
Logger.get().debug(TAG, "Ignoring " + workSpec + ". Requires device idle.");
} else if (constraints.hasContentUriTriggers()) {
Logger.get().debug(TAG, "Ignoring " + workSpec + ". Requires ContentUri triggers.");
} else {
hashSet.add(workSpec);
hashSet2.add(workSpec.id);
}
} else if (!this.mStartStopTokens.contains(WorkSpecKt.generationalId(workSpec))) {
Logger.get().debug(TAG, "Starting work for " + workSpec.id);
StartStopToken startStopToken = this.mStartStopTokens.tokenFor(workSpec);
this.mTimeLimiter.track(startStopToken);
this.mWorkLauncher.startWork(startStopToken);
}
}
}
}
synchronized (this.mLock) {
try {
if (!hashSet.isEmpty()) {
Logger.get().debug(TAG, "Starting tracking for " + TextUtils.join(",", hashSet2));
for (WorkSpec workSpec2 : hashSet) {
WorkGenerationalId generationalId = WorkSpecKt.generationalId(workSpec2);
if (!this.mConstrainedWorkSpecs.containsKey(generationalId)) {
this.mConstrainedWorkSpecs.put(generationalId, WorkConstraintsTrackerKt.listen(this.mConstraintsTracker, workSpec2, this.mTaskExecutor.getTaskCoroutineDispatcher(), this));
}
}
}
} catch (Throwable th) {
throw th;
}
}
}
private void checkDefaultProcess() {
this.mInDefaultProcess = Boolean.valueOf(ProcessUtils.isDefaultProcess(this.mContext, this.mConfiguration));
}
@Override // androidx.work.impl.Scheduler
public void cancel(@NonNull String str) {
if (this.mInDefaultProcess == null) {
checkDefaultProcess();
}
if (!this.mInDefaultProcess.booleanValue()) {
Logger.get().info(TAG, "Ignoring schedule request in non-main process");
return;
}
registerExecutionListenerIfNeeded();
Logger.get().debug(TAG, "Cancelling work ID " + str);
DelayedWorkTracker delayedWorkTracker = this.mDelayedWorkTracker;
if (delayedWorkTracker != null) {
delayedWorkTracker.unschedule(str);
}
for (StartStopToken startStopToken : this.mStartStopTokens.remove(str)) {
this.mTimeLimiter.cancel(startStopToken);
this.mWorkLauncher.stopWork(startStopToken);
}
}
@Override // androidx.work.impl.constraints.OnConstraintsStateChangedListener
public void onConstraintsStateChanged(@NonNull WorkSpec workSpec, @NonNull ConstraintsState constraintsState) {
WorkGenerationalId generationalId = WorkSpecKt.generationalId(workSpec);
if (constraintsState instanceof ConstraintsState.ConstraintsMet) {
if (this.mStartStopTokens.contains(generationalId)) {
return;
}
Logger.get().debug(TAG, "Constraints met: Scheduling work ID " + generationalId);
StartStopToken startStopToken = this.mStartStopTokens.tokenFor(generationalId);
this.mTimeLimiter.track(startStopToken);
this.mWorkLauncher.startWork(startStopToken);
return;
}
Logger.get().debug(TAG, "Constraints not met: Cancelling work ID " + generationalId);
StartStopToken remove = this.mStartStopTokens.remove(generationalId);
if (remove != null) {
this.mTimeLimiter.cancel(remove);
this.mWorkLauncher.stopWorkWithReason(remove, ((ConstraintsState.ConstraintsNotMet) constraintsState).getReason());
}
}
@Override // androidx.work.impl.ExecutionListener
public void onExecuted(@NonNull WorkGenerationalId workGenerationalId, boolean z) {
StartStopToken remove = this.mStartStopTokens.remove(workGenerationalId);
if (remove != null) {
this.mTimeLimiter.cancel(remove);
}
removeConstraintTrackingFor(workGenerationalId);
if (z) {
return;
}
synchronized (this.mLock) {
this.mFirstRunAttempts.remove(workGenerationalId);
}
}
private void removeConstraintTrackingFor(@NonNull WorkGenerationalId workGenerationalId) {
Job remove;
synchronized (this.mLock) {
remove = this.mConstrainedWorkSpecs.remove(workGenerationalId);
}
if (remove != null) {
Logger.get().debug(TAG, "Stopping tracking for " + workGenerationalId);
remove.cancel(null);
}
}
private void registerExecutionListenerIfNeeded() {
if (this.mRegisteredExecutionListener) {
return;
}
this.mProcessor.addExecutionListener(this);
this.mRegisteredExecutionListener = true;
}
private long throttleIfNeeded(WorkSpec workSpec) {
long max;
synchronized (this.mLock) {
try {
WorkGenerationalId generationalId = WorkSpecKt.generationalId(workSpec);
AttemptData attemptData = this.mFirstRunAttempts.get(generationalId);
if (attemptData == null) {
attemptData = new AttemptData(workSpec.runAttemptCount, this.mConfiguration.getClock().currentTimeMillis());
this.mFirstRunAttempts.put(generationalId, attemptData);
}
max = attemptData.mTimeStamp + (Math.max((workSpec.runAttemptCount - attemptData.mRunAttemptCount) - 5, 0) * WorkRequest.DEFAULT_BACKOFF_DELAY_MILLIS);
} catch (Throwable th) {
throw th;
}
}
return max;
}
public static class AttemptData {
final int mRunAttemptCount;
final long mTimeStamp;
private AttemptData(int i, long j) {
this.mRunAttemptCount = i;
this.mTimeStamp = j;
}
}
}