Prevent redundant JobScheduler jobs.

Some devices actually enforce a scheduling rate, and will crash if you
submit more than, say, 250 jobs in 1 minute. This can happen when
catching up with messages and scheduling a lot of
PushDecryptMessageJobs.

While it'd be tricky to limit jobs with constraints, this just does the
simple thing of not enqueueing unnecessary jobs for constraint-less
jobs.
master
Greyson Parrelli 2020-09-15 10:20:20 -04:00
parent 5943b9d7d6
commit 7108fc81a9
1 changed files with 15 additions and 4 deletions

View File

@ -11,7 +11,6 @@ import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.logging.Log;
@ -36,7 +35,15 @@ public class JobSchedulerScheduler implements Scheduler {
@RequiresApi(26)
@Override
public void schedule(long delay, @NonNull List<Constraint> constraints) {
JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(getNextId(), new ComponentName(application, SystemService.class))
JobScheduler jobScheduler = application.getSystemService(JobScheduler.class);
int currentId = getCurrentId();
if (constraints.isEmpty() && jobScheduler.getPendingJob(currentId) != null) {
Log.d(TAG, "Skipping JobScheduler enqueue because we have no constraints and there's already one pending.");
return;
}
JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(getAndUpdateNextId(), new ComponentName(application, SystemService.class))
.setMinimumLatency(delay)
.setPersisted(true);
@ -44,11 +51,15 @@ public class JobSchedulerScheduler implements Scheduler {
constraint.applyToJobInfo(jobInfoBuilder);
}
JobScheduler jobScheduler = application.getSystemService(JobScheduler.class);
jobScheduler.schedule(jobInfoBuilder.build());
}
private int getNextId() {
private int getCurrentId() {
SharedPreferences prefs = application.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
return prefs.getInt(PREF_NEXT_ID, 0);
}
private int getAndUpdateNextId() {
SharedPreferences prefs = application.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
int returnedId = prefs.getInt(PREF_NEXT_ID, 0);
int nextId = returnedId + 1 > MAX_ID ? 0 : returnedId + 1;