2021-07-24 02:37:17 +00:00
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.work.Logger ;
import androidx.work.WorkInfo ;
import androidx.work.impl.Scheduler ;
import androidx.work.impl.WorkDatabase ;
import androidx.work.impl.WorkManagerImpl ;
import androidx.work.impl.model.SystemIdInfo ;
import androidx.work.impl.model.WorkSpec ;
import androidx.work.impl.utils.IdGenerator ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Locale ;
@RequiresApi ( 23 )
@RestrictTo ( { RestrictTo . Scope . LIBRARY_GROUP } )
public class SystemJobScheduler implements Scheduler {
private static final String TAG = Logger . tagWithPrefix ( " SystemJobScheduler " ) ;
private final Context mContext ;
private final JobScheduler mJobScheduler ;
private final SystemJobInfoConverter mSystemJobInfoConverter ;
private final WorkManagerImpl mWorkManager ;
public SystemJobScheduler ( @NonNull Context context , @NonNull WorkManagerImpl workManagerImpl ) {
this ( context , workManagerImpl , ( JobScheduler ) context . getSystemService ( " jobscheduler " ) , new SystemJobInfoConverter ( context ) ) ;
}
@VisibleForTesting
public SystemJobScheduler ( Context context , WorkManagerImpl workManagerImpl , JobScheduler jobScheduler , SystemJobInfoConverter systemJobInfoConverter ) {
this . mContext = context ;
this . mWorkManager = workManagerImpl ;
this . mJobScheduler = jobScheduler ;
this . mSystemJobInfoConverter = systemJobInfoConverter ;
}
public static void cancelAll ( @NonNull Context context ) {
List < JobInfo > pendingJobs ;
JobScheduler jobScheduler = ( JobScheduler ) context . getSystemService ( " jobscheduler " ) ;
if ( ! ( jobScheduler = = null | | ( pendingJobs = getPendingJobs ( context , jobScheduler ) ) = = null | | pendingJobs . isEmpty ( ) ) ) {
for ( JobInfo jobInfo : pendingJobs ) {
cancelJobById ( jobScheduler , jobInfo . getId ( ) ) ;
}
}
}
public static void cancelInvalidJobs ( @NonNull Context context ) {
List < JobInfo > pendingJobs ;
JobScheduler jobScheduler = ( JobScheduler ) context . getSystemService ( " jobscheduler " ) ;
if ( ! ( jobScheduler = = null | | ( pendingJobs = getPendingJobs ( context , jobScheduler ) ) = = null | | pendingJobs . isEmpty ( ) ) ) {
for ( JobInfo jobInfo : pendingJobs ) {
if ( getWorkSpecIdFromJobInfo ( jobInfo ) = = null ) {
cancelJobById ( jobScheduler , jobInfo . getId ( ) ) ;
}
}
}
}
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 ) ;
}
}
@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 ) {
if ( str . equals ( getWorkSpecIdFromJobInfo ( jobInfo ) ) ) {
arrayList . add ( Integer . valueOf ( jobInfo . getId ( ) ) ) ;
}
}
return arrayList ;
}
@Nullable
private static List < JobInfo > getPendingJobs ( @NonNull Context context , @NonNull JobScheduler jobScheduler ) {
List < JobInfo > list ;
try {
list = jobScheduler . getAllPendingJobs ( ) ;
} catch ( Throwable th ) {
Logger . get ( ) . error ( TAG , " getAllPendingJobs() is not reliable on this device. " , th ) ;
list = null ;
}
if ( list = = null ) {
return null ;
}
ArrayList arrayList = new ArrayList ( list . size ( ) ) ;
ComponentName componentName = new ComponentName ( context , SystemJobService . class ) ;
for ( JobInfo jobInfo : list ) {
if ( componentName . equals ( jobInfo . getService ( ) ) ) {
arrayList . add ( jobInfo ) ;
}
}
return arrayList ;
}
@Nullable
private static String getWorkSpecIdFromJobInfo ( @NonNull JobInfo jobInfo ) {
PersistableBundle extras = jobInfo . getExtras ( ) ;
if ( extras = = null ) {
return null ;
}
try {
2021-08-09 22:50:52 +00:00
if ( extras . containsKey ( SystemJobInfoConverter . EXTRA_WORK_SPEC_ID ) ) {
return extras . getString ( SystemJobInfoConverter . EXTRA_WORK_SPEC_ID ) ;
2021-07-24 02:37:17 +00:00
}
return null ;
} catch ( NullPointerException unused ) {
return null ;
}
}
@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 ( ) ) ) {
for ( Integer num : pendingJobIds ) {
cancelJobById ( this . mJobScheduler , num . intValue ( ) ) ;
}
this . mWorkManager . getWorkDatabase ( ) . systemIdInfoDao ( ) . removeSystemIdInfo ( str ) ;
}
}
@Override // androidx.work.impl.Scheduler
public boolean hasLimitedSchedulingSlots ( ) {
return true ;
}
/* JADX INFO: finally extract failed */
@Override // androidx.work.impl.Scheduler
public void schedule ( @NonNull WorkSpec . . . workSpecArr ) {
List < Integer > pendingJobIds ;
WorkDatabase workDatabase = this . mWorkManager . getWorkDatabase ( ) ;
IdGenerator idGenerator = new IdGenerator ( workDatabase ) ;
for ( WorkSpec workSpec : workSpecArr ) {
workDatabase . beginTransaction ( ) ;
try {
2021-08-10 10:47:20 +00:00
WorkSpec workSpec2 = workDatabase . workSpecDao ( ) . getWorkSpec ( workSpec . f29id ) ;
2021-07-24 02:37:17 +00:00
if ( workSpec2 = = null ) {
2021-08-10 10:47:20 +00:00
Logger . get ( ) . warning ( TAG , " Skipping scheduling " + workSpec . f29id + " because it's no longer in the DB " , new Throwable [ 0 ] ) ;
2021-07-24 02:37:17 +00:00
workDatabase . setTransactionSuccessful ( ) ;
} else if ( workSpec2 . state ! = WorkInfo . State . ENQUEUED ) {
2021-08-10 10:47:20 +00:00
Logger . get ( ) . warning ( TAG , " Skipping scheduling " + workSpec . f29id + " because it is no longer enqueued " , new Throwable [ 0 ] ) ;
2021-07-24 02:37:17 +00:00
workDatabase . setTransactionSuccessful ( ) ;
} else {
2021-08-10 10:47:20 +00:00
SystemIdInfo systemIdInfo = workDatabase . systemIdInfoDao ( ) . getSystemIdInfo ( workSpec . f29id ) ;
2021-07-24 02:37:17 +00:00
int nextJobSchedulerIdWithRange = systemIdInfo ! = null ? systemIdInfo . systemId : idGenerator . nextJobSchedulerIdWithRange ( this . mWorkManager . getConfiguration ( ) . getMinJobSchedulerId ( ) , this . mWorkManager . getConfiguration ( ) . getMaxJobSchedulerId ( ) ) ;
if ( systemIdInfo = = null ) {
2021-08-10 10:47:20 +00:00
this . mWorkManager . getWorkDatabase ( ) . systemIdInfoDao ( ) . insertSystemIdInfo ( new SystemIdInfo ( workSpec . f29id , nextJobSchedulerIdWithRange ) ) ;
2021-07-24 02:37:17 +00:00
}
scheduleInternal ( workSpec , nextJobSchedulerIdWithRange ) ;
2021-08-10 10:47:20 +00:00
if ( Build . VERSION . SDK_INT = = 23 & & ( pendingJobIds = getPendingJobIds ( this . mContext , this . mJobScheduler , workSpec . f29id ) ) ! = null ) {
2021-07-24 02:37:17 +00:00
int indexOf = pendingJobIds . indexOf ( Integer . valueOf ( nextJobSchedulerIdWithRange ) ) ;
if ( indexOf > = 0 ) {
pendingJobIds . remove ( indexOf ) ;
}
scheduleInternal ( workSpec , ! pendingJobIds . isEmpty ( ) ? pendingJobIds . get ( 0 ) . intValue ( ) : idGenerator . nextJobSchedulerIdWithRange ( this . mWorkManager . getConfiguration ( ) . getMinJobSchedulerId ( ) , this . mWorkManager . getConfiguration ( ) . getMaxJobSchedulerId ( ) ) ) ;
}
workDatabase . setTransactionSuccessful ( ) ;
}
workDatabase . endTransaction ( ) ;
} catch ( Throwable th ) {
workDatabase . endTransaction ( ) ;
throw th ;
}
}
}
@VisibleForTesting
public void scheduleInternal ( WorkSpec workSpec , int i ) {
JobInfo convert = this . mSystemJobInfoConverter . convert ( workSpec , i ) ;
2021-08-10 10:47:20 +00:00
Logger . get ( ) . debug ( TAG , String . format ( " Scheduling work ID %s Job ID %s " , workSpec . f29id , Integer . valueOf ( i ) ) , new Throwable [ 0 ] ) ;
2021-07-24 02:37:17 +00:00
try {
this . mJobScheduler . schedule ( convert ) ;
} catch ( IllegalStateException e ) {
List < JobInfo > pendingJobs = getPendingJobs ( this . mContext , this . mJobScheduler ) ;
String format = String . format ( Locale . getDefault ( ) , " JobScheduler 100 job limit exceeded. We count %d WorkManager jobs in JobScheduler; we have %d tracked jobs in our DB; our Configuration limit is %d. " , Integer . valueOf ( pendingJobs ! = null ? pendingJobs . size ( ) : 0 ) , Integer . valueOf ( this . mWorkManager . getWorkDatabase ( ) . workSpecDao ( ) . getScheduledWork ( ) . size ( ) ) , Integer . valueOf ( this . mWorkManager . getConfiguration ( ) . getMaxSchedulerLimit ( ) ) ) ;
Logger . get ( ) . error ( TAG , format , new Throwable [ 0 ] ) ;
throw new IllegalStateException ( format , e ) ;
} catch ( Throwable th ) {
Logger . get ( ) . error ( TAG , String . format ( " Unable to schedule %s " , workSpec ) , th ) ;
}
}
}