work/workmanager/src/main/java/androidx/work/impl/utils/EnqueueRunnable.java
private static boolean enqueueWorkWithPrerequisites(
            WorkManagerImpl workManagerImpl,
            @NonNull List<? extends WorkRequest> workList,
            String[] prerequisiteIds,
            String name,
            ExistingWorkPolicy existingWorkPolicy) {

        long currentTimeMillis = System.currentTimeMillis();
        WorkDatabase workDatabase = workManagerImpl.getWorkDatabase();

        boolean hasPrerequisite = (prerequisiteIds != null && prerequisiteIds.length > 0);
        boolean hasCompletedAllPrerequisites = true;
        boolean hasFailedPrerequisites = false;
        boolean hasCancelledPrerequisites = false;

        if (hasPrerequisite) {
            // If there are prerequisites, make sure they actually exist before enqueuing
            // anything.  Prerequisites may not exist if we are using unique tags, because the
            // chain of work could have been wiped out already.
            for (String id : prerequisiteIds) {
                WorkSpec prerequisiteWorkSpec = workDatabase.workSpecDao().getWorkSpec(id);
                if (prerequisiteWorkSpec == null) {
                    Log.e(TAG, String.format("Prerequisite %s doesn't exist; not enqueuing", id));
                    return false;
                }

                State prerequisiteState = prerequisiteWorkSpec.state;
                hasCompletedAllPrerequisites &= (prerequisiteState == SUCCEEDED);
                if (prerequisiteState == FAILED) {
                    hasFailedPrerequisites = true;
                } else if (prerequisiteState == CANCELLED) {
                    hasCancelledPrerequisites = true;
                }
            }
        }

        boolean isNamed = !TextUtils.isEmpty(name);

        // We only apply existing work policies for unique tag sequences that are the beginning of
        // chains.
        boolean shouldApplyExistingWorkPolicy = isNamed && !hasPrerequisite;
        if (shouldApplyExistingWorkPolicy) {
            // Get everything with the unique tag.
            List<WorkSpec.IdAndState> existingWorkSpecIdAndStates =
                    workDatabase.workSpecDao().getWorkSpecIdAndStatesForName(name);

            if (!existingWorkSpecIdAndStates.isEmpty()) {
                // If appending, these are the new prerequisites.
                if (existingWorkPolicy == APPEND) {
                    DependencyDao dependencyDao = workDatabase.dependencyDao();
                    List<String> newPrerequisiteIds = new ArrayList<>();
                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                        if (!dependencyDao.hasDependents(idAndState.id)) {
                            hasCompletedAllPrerequisites &= (idAndState.state == SUCCEEDED);
                            if (idAndState.state == FAILED) {
                                hasFailedPrerequisites = true;
                            } else if (idAndState.state == CANCELLED) {
                                hasCancelledPrerequisites = true;
                            }
                            newPrerequisiteIds.add(idAndState.id);
                        }
                    }
                    prerequisiteIds = newPrerequisiteIds.toArray(prerequisiteIds);
                    hasPrerequisite = (prerequisiteIds.length > 0);
                } else {
                    // If we're keeping existing work, make sure to do so only if something is
                    // enqueued or running.
                    if (existingWorkPolicy == KEEP) {
                        for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                            if (idAndState.state == ENQUEUED || idAndState.state == RUNNING) {
                                return false;
                            }
                        }
                    }

                    // Cancel all of these workers.
                    CancelWorkRunnable.forName(name, workManagerImpl).run();
                    // And delete all the database records.
                    WorkSpecDao workSpecDao = workDatabase.workSpecDao();
                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                        workSpecDao.delete(idAndState.id);
                    }
                }
            }
        }

        boolean needsScheduling = false;
        for (WorkRequest work : workList) {
            WorkSpec workSpec = work.getWorkSpec();

            if (hasPrerequisite && !hasCompletedAllPrerequisites) {
                if (hasFailedPrerequisites) {
                    workSpec.state = FAILED;
                } else if (hasCancelledPrerequisites) {
                    workSpec.state = CANCELLED;
                } else {
                    workSpec.state = BLOCKED;
                }
            } else {
                // Set scheduled times only for work without prerequisites. Dependent work
                // will set their scheduled times when they are unblocked.
                workSpec.periodStartTime = currentTimeMillis;
            }

            if (Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT <= 25) {
                tryDelegateConstrainedWorkSpec(workSpec);
            }

            // If we have one WorkSpec with an enqueued state, then we need to schedule.
            if (workSpec.state == ENQUEUED) {
                needsScheduling = true;
            }

            workDatabase.workSpecDao().insertWorkSpec(workSpec);

            if (hasPrerequisite) {
                for (String prerequisiteId : prerequisiteIds) {
                    Dependency dep = new Dependency(work.getStringId(), prerequisiteId);
                    workDatabase.dependencyDao().insertDependency(dep);
                }
            }

            for (String tag : work.getTags()) {
                workDatabase.workTagDao().insert(new WorkTag(tag, work.getStringId()));
            }

            if (isNamed) {
                workDatabase.workNameDao().insert(new WorkName(name, work.getStringId()));
            }
        }
        return needsScheduling;
    }
/**
     * Enqueues the {@link WorkSpec}'s while keeping track of the prerequisites.
     *
     * @return {@code true} If there is any scheduling to be done.
     */
Enqueues the  WorkSpec's while keeping track of the prerequisites.
@return  true If there is any scheduling to be done.
Enqueues the WorkSpec ' s while keeping track of the prerequisites . @return true If there is any scheduling to be done .
private static boolean enqueueWorkWithPrerequisites(
            WorkManagerImpl workManagerImpl,
            @NonNull List<? extends WorkRequest> workList,
            String[] prerequisiteIds,
            String name,
            ExistingWorkPolicy existingWorkPolicy) {
        long currentTimeMillis = System.currentTimeMillis();
        WorkDatabase workDatabase = workManagerImpl.getWorkDatabase();
        boolean hasPrerequisite = (prerequisiteIds != null && prerequisiteIds.length > 0);
        boolean hasCompletedAllPrerequisites = true;
        boolean hasFailedPrerequisites = false;
        boolean hasCancelledPrerequisites = false;
        if (hasPrerequisite) {
            for (String id : prerequisiteIds) {
                WorkSpec prerequisiteWorkSpec = workDatabase.workSpecDao().getWorkSpec(id);
                if (prerequisiteWorkSpec == null) {
                    Log.e(TAG, String.format("Prerequisite %s doesn't exist; not enqueuing", id));
                    return false;
                }
                State prerequisiteState = prerequisiteWorkSpec.state;
                hasCompletedAllPrerequisites &= (prerequisiteState == SUCCEEDED);
                if (prerequisiteState == FAILED) {
                    hasFailedPrerequisites = true;
                } else if (prerequisiteState == CANCELLED) {
                    hasCancelledPrerequisites = true;
                }
            }
        }
        boolean isNamed = !TextUtils.isEmpty(name);
        boolean shouldApplyExistingWorkPolicy = isNamed && !hasPrerequisite;
        if (shouldApplyExistingWorkPolicy) {
            List<WorkSpec.IdAndState> existingWorkSpecIdAndStates =
                    workDatabase.workSpecDao().getWorkSpecIdAndStatesForName(name);
            if (!existingWorkSpecIdAndStates.isEmpty()) {
                if (existingWorkPolicy == APPEND) {
                    DependencyDao dependencyDao = workDatabase.dependencyDao();
                    List<String> newPrerequisiteIds = new ArrayList<>();
                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                        if (!dependencyDao.hasDependents(idAndState.id)) {
                            hasCompletedAllPrerequisites &= (idAndState.state == SUCCEEDED);
                            if (idAndState.state == FAILED) {
                                hasFailedPrerequisites = true;
                            } else if (idAndState.state == CANCELLED) {
                                hasCancelledPrerequisites = true;
                            }
                            newPrerequisiteIds.add(idAndState.id);
                        }
                    }
                    prerequisiteIds = newPrerequisiteIds.toArray(prerequisiteIds);
                    hasPrerequisite = (prerequisiteIds.length > 0);
                } else {
                    if (existingWorkPolicy == KEEP) {
                        for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                            if (idAndState.state == ENQUEUED || idAndState.state == RUNNING) {
                                return false;
                            }
                        }
                    }
                    CancelWorkRunnable.forName(name, workManagerImpl).run();
                    WorkSpecDao workSpecDao = workDatabase.workSpecDao();
                    for (WorkSpec.IdAndState idAndState : existingWorkSpecIdAndStates) {
                        workSpecDao.delete(idAndState.id);
                    }
                }
            }
        }
        boolean needsScheduling = false;
        for (WorkRequest work : workList) {
            WorkSpec workSpec = work.getWorkSpec();
            if (hasPrerequisite && !hasCompletedAllPrerequisites) {
                if (hasFailedPrerequisites) {
                    workSpec.state = FAILED;
                } else if (hasCancelledPrerequisites) {
                    workSpec.state = CANCELLED;
                } else {
                    workSpec.state = BLOCKED;
                }
            } else {
                workSpec.periodStartTime = currentTimeMillis;
            }
            if (Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT <= 25) {
                tryDelegateConstrainedWorkSpec(workSpec);
            }
            if (workSpec.state == ENQUEUED) {
                needsScheduling = true;
            }
            workDatabase.workSpecDao().insertWorkSpec(workSpec);
            if (hasPrerequisite) {
                for (String prerequisiteId : prerequisiteIds) {
                    Dependency dep = new Dependency(work.getStringId(), prerequisiteId);
                    workDatabase.dependencyDao().insertDependency(dep);
                }
            }
            for (String tag : work.getTags()) {
                workDatabase.workTagDao().insert(new WorkTag(tag, work.getStringId()));
            }
            if (isNamed) {
                workDatabase.workNameDao().insert(new WorkName(name, work.getStringId()));
            }
        }
        return needsScheduling;
    }
private static boolean enqueueWorkWithPrerequisites ( WorkManagerImpl workManagerImpl , @ NonNull List < ? extends WorkRequest > workList , String [ ] prerequisiteIds , String name , ExistingWorkPolicy existingWorkPolicy ) { long currentTimeMillis = System . currentTimeMillis ( ) ; WorkDatabase workDatabase = workManagerImpl . getWorkDatabase ( ) ; boolean hasPrerequisite = ( prerequisiteIds != null && prerequisiteIds . length > 0 ) ; boolean hasCompletedAllPrerequisites = true ; boolean hasFailedPrerequisites = false ; boolean hasCancelledPrerequisites = false ; if ( hasPrerequisite ) { for ( String id : prerequisiteIds ) { WorkSpec prerequisiteWorkSpec = workDatabase . workSpecDao ( ) . getWorkSpec ( id ) ; if ( prerequisiteWorkSpec == null ) { Log . e ( TAG , String . format ( "Prerequisite %s doesn't exist; not enqueuing" , id ) ) ; return false ; } State prerequisiteState = prerequisiteWorkSpec . state ; hasCompletedAllPrerequisites &= ( prerequisiteState == SUCCEEDED ) ; if ( prerequisiteState == FAILED ) { hasFailedPrerequisites = true ; } else if ( prerequisiteState == CANCELLED ) { hasCancelledPrerequisites = true ; } } } boolean isNamed = ! TextUtils . isEmpty ( name ) ; boolean shouldApplyExistingWorkPolicy = isNamed && ! hasPrerequisite ; if ( shouldApplyExistingWorkPolicy ) { List < WorkSpec . IdAndState > existingWorkSpecIdAndStates = workDatabase . workSpecDao ( ) . getWorkSpecIdAndStatesForName ( name ) ; if ( ! existingWorkSpecIdAndStates . isEmpty ( ) ) { if ( existingWorkPolicy == APPEND ) { DependencyDao dependencyDao = workDatabase . dependencyDao ( ) ; List < String > newPrerequisiteIds = new ArrayList < > ( ) ; for ( WorkSpec . IdAndState idAndState : existingWorkSpecIdAndStates ) { if ( ! dependencyDao . hasDependents ( idAndState . id ) ) { hasCompletedAllPrerequisites &= ( idAndState . state == SUCCEEDED ) ; if ( idAndState . state == FAILED ) { hasFailedPrerequisites = true ; } else if ( idAndState . state == CANCELLED ) { hasCancelledPrerequisites = true ; } newPrerequisiteIds . add ( idAndState . id ) ; } } prerequisiteIds = newPrerequisiteIds . toArray ( prerequisiteIds ) ; hasPrerequisite = ( prerequisiteIds . length > 0 ) ; } else { if ( existingWorkPolicy == KEEP ) { for ( WorkSpec . IdAndState idAndState : existingWorkSpecIdAndStates ) { if ( idAndState . state == ENQUEUED || idAndState . state == RUNNING ) { return false ; } } } CancelWorkRunnable . forName ( name , workManagerImpl ) . run ( ) ; WorkSpecDao workSpecDao = workDatabase . workSpecDao ( ) ; for ( WorkSpec . IdAndState idAndState : existingWorkSpecIdAndStates ) { workSpecDao . delete ( idAndState . id ) ; } } } } boolean needsScheduling = false ; for ( WorkRequest work : workList ) { WorkSpec workSpec = work . getWorkSpec ( ) ; if ( hasPrerequisite && ! hasCompletedAllPrerequisites ) { if ( hasFailedPrerequisites ) { workSpec . state = FAILED ; } else if ( hasCancelledPrerequisites ) { workSpec . state = CANCELLED ; } else { workSpec . state = BLOCKED ; } } else { workSpec . periodStartTime = currentTimeMillis ; } if ( Build . VERSION . SDK_INT >= 23 && Build . VERSION . SDK_INT <= 25 ) { tryDelegateConstrainedWorkSpec ( workSpec ) ; } if ( workSpec . state == ENQUEUED ) { needsScheduling = true ; } workDatabase . workSpecDao ( ) . insertWorkSpec ( workSpec ) ; if ( hasPrerequisite ) { for ( String prerequisiteId : prerequisiteIds ) { Dependency dep = new Dependency ( work . getStringId ( ) , prerequisiteId ) ; workDatabase . dependencyDao ( ) . insertDependency ( dep ) ; } } for ( String tag : work . getTags ( ) ) { workDatabase . workTagDao ( ) . insert ( new WorkTag ( tag , work . getStringId ( ) ) ) ; } if ( isNamed ) { workDatabase . workNameDao ( ) . insert ( new WorkName ( name , work . getStringId ( ) ) ) ; } } return needsScheduling ; }
Enqueues the {@link WorkSpec}'s while keeping track of the prerequisites.
Enqueues the { @link WorkSpec } ' s while keeping track of the prerequisites .
// If there are prerequisites, make sure they actually exist before enqueuing // anything.  Prerequisites may not exist if we are using unique tags, because the // chain of work could have been wiped out already. // We only apply existing work policies for unique tag sequences that are the beginning of // chains. // Get everything with the unique tag. // If appending, these are the new prerequisites. // If we're keeping existing work, make sure to do so only if something is // enqueued or running. // Cancel all of these workers. // And delete all the database records. // Set scheduled times only for work without prerequisites. Dependent work // will set their scheduled times when they are unblocked. // If we have one WorkSpec with an enqueued state, then we need to schedule.