2929import static com .google .devtools .mobileharness .shared .util .time .TimeUtils .toProtoDuration ;
3030import static com .google .devtools .mobileharness .shared .util .time .TimeUtils .toProtoTimestamp ;
3131import static java .util .Arrays .stream ;
32+ import static java .util .stream .Collectors .partitioningBy ;
3233
3334import com .google .common .annotations .VisibleForTesting ;
3435import com .google .common .base .Ascii ;
109110import java .util .List ;
110111import java .util .Map ;
111112import java .util .Optional ;
113+ import java .util .Queue ;
112114import java .util .Set ;
113115import java .util .concurrent .ConcurrentHashMap ;
116+ import java .util .concurrent .ConcurrentLinkedQueue ;
114117import java .util .concurrent .atomic .AtomicInteger ;
115118import java .util .concurrent .atomic .AtomicReference ;
116119import java .util .function .UnaryOperator ;
@@ -170,19 +173,15 @@ public class AtsSessionPlugin {
170173 @ GuardedBy ("addingJobLock" )
171174 private boolean sessionEnded ;
172175
173- @ GuardedBy ("itself" )
174- private final List <JobInfo > additionalTradefedJobs = new ArrayList <>();
176+ private final Queue <JobInfo > additionalTradefedJobs = new ConcurrentLinkedQueue <>();
175177
176178 /** Set in {@link #onSessionStarting}. */
177179 private volatile AtsSessionPluginConfig config ;
178180
179181 private volatile ImmutableList <JobInfo > tradefedJobs = ImmutableList .of ();
180182 private volatile ImmutableList <JobInfo > nonTradefedJobs = ImmutableList .of ();
181183
182- private final Object setupJobLock = new Object ();
183-
184- @ GuardedBy ("setupJobLock" )
185- private Optional <String > runningSetupJobId = Optional .empty ();
184+ private final AtomicReference <String > runningSetupJobId = new AtomicReference <>();
186185
187186 @ Inject
188187 AtsSessionPlugin (
@@ -420,13 +419,7 @@ public void onJobEnd(JobEndEvent jobEndEvent)
420419 }
421420
422421 String jobId = currentJob .locator ().getId ();
423- boolean isSetupJobEnd = false ;
424- synchronized (setupJobLock ) {
425- if (runningSetupJobId .isPresent () && runningSetupJobId .get ().equals (jobId )) {
426- runningSetupJobId = Optional .empty ();
427- isSetupJobEnd = true ;
428- }
429- }
422+ boolean isSetupJobEnd = runningSetupJobId .compareAndSet (jobId , null );
430423 if (isSetupJobEnd ) {
431424 logger .atInfo ().log ("Setup job [%s] ended, starting main jobs." , jobId );
432425 addMainJobs ();
@@ -440,35 +433,14 @@ public void onJobEnd(JobEndEvent jobEndEvent)
440433 runningTradefedJobs .put (jobId , false );
441434
442435 // Add the additional tradefed jobs if needed.
443- synchronized (additionalTradefedJobs ) {
444- if (!additionalTradefedJobs .isEmpty ()) {
445- ImmutableSet <String > devicesOfCurrentJob = getDeviceSerials (currentJob );
446- JobInfo nextJobToAdd = additionalTradefedJobs .remove (0 );
447- // Add the device ids of the current job to the sub device specs of the next tradefed job.
448- addDeviceIdsToSubDeviceSpecs (
449- nextJobToAdd .subDeviceSpecs ().getAllSubDevices (), devicesOfCurrentJob );
450- if (nextJobToAdd
451- .properties ()
452- .getBoolean (XtsConstants .IS_XTS_DYNAMIC_DOWNLOAD_ENABLED )
453- .orElse (false )) {
454- // Copy test properties needed by xTS dynamic download jobs from the current test to
455- // the next tests.
456- currentJob .tests ().getAll ().values ().stream ()
457- .findFirst ()
458- .ifPresent (
459- currentTest ->
460- nextJobToAdd
461- .tests ()
462- .getAll ()
463- .values ()
464- .forEach (
465- nextTest ->
466- copyTestPropertiesForDynamicDownloadJobs (
467- currentTest , nextTest )));
468- }
469-
470- addAndTrackTradefedJobs (ImmutableList .of (nextJobToAdd ));
471- }
436+ JobInfo nextJobToAdd = additionalTradefedJobs .poll ();
437+ if (nextJobToAdd != null ) {
438+ ImmutableSet <String > devicesOfCurrentJob = getDeviceSerials (currentJob );
439+ // Add the device ids of the current job to the sub device specs of the next tradefed job.
440+ addDeviceIdsToSubDeviceSpecs (
441+ nextJobToAdd .subDeviceSpecs ().getAllSubDevices (), devicesOfCurrentJob );
442+ copyDynamicDownloadProperties (currentJob , nextJobToAdd );
443+ addAndTrackTradefedJobs (ImmutableList .of (nextJobToAdd ));
472444 }
473445
474446 if (runningTradefedJobs .values ().stream ().noneMatch (running -> running )) {
@@ -717,6 +689,7 @@ private void onSessionCancellation(AtsSessionCancellation sessionCancellation) {
717689 synchronized (addingJobLock ) {
718690 this .sessionCancellation = sessionCancellation ;
719691 }
692+ additionalTradefedJobs .clear ();
720693
721694 int killTradefedSignal ;
722695 if (sessionCancellation .hasSignal ()) {
@@ -833,9 +806,7 @@ private void addSetupJob(JobInfo setupJob) {
833806 nonTradefedJobs .stream ().filter (job -> !job .equals (setupJob )).collect (toImmutableList ());
834807 ImmutableList <String > setupJobIds = addJobsToSession (ImmutableList .of (setupJob ));
835808 if (!setupJobIds .isEmpty ()) {
836- synchronized (setupJobLock ) {
837- runningSetupJobId = Optional .of (setupJobIds .get (0 ));
838- }
809+ runningSetupJobId .set (setupJobIds .get (0 ));
839810 }
840811 }
841812
@@ -857,25 +828,21 @@ private void addMainJobs() {
857828 if (tradefedJobs .size () <= 1 ) {
858829 startedTfJobs = addAndTrackTradefedJobs (tradefedJobs );
859830 } else {
860- List <JobInfo > staticXtsJobs = new ArrayList <>();
861- synchronized (additionalTradefedJobs ) {
862- tradefedJobs .forEach (
863- tradefedJob -> {
864- if (tradefedJob .locator ().getName ().contains (XtsConstants .STATIC_XTS_JOB_NAME )) {
865- staticXtsJobs .add (tradefedJob );
866- } else {
867- additionalTradefedJobs .add (tradefedJob );
868- }
869- });
870- }
831+ Map <Boolean , List <JobInfo >> partitionedJobs =
832+ tradefedJobs .stream ()
833+ .collect (
834+ partitioningBy (
835+ job -> job .locator ().getName ().contains (XtsConstants .STATIC_XTS_JOB_NAME )));
836+
837+ List <JobInfo > staticXtsJobs = partitionedJobs .get (true );
838+ additionalTradefedJobs .addAll (partitionedJobs .get (false ));
839+
871840 if (!staticXtsJobs .isEmpty ()) {
872841 startedTfJobs = addAndTrackTradefedJobs (staticXtsJobs );
873842 } else {
874- synchronized (additionalTradefedJobs ) {
875- if (!additionalTradefedJobs .isEmpty ()) {
876- startedTfJobs =
877- addAndTrackTradefedJobs (ImmutableList .of (additionalTradefedJobs .remove (0 )));
878- }
843+ JobInfo nextJob = additionalTradefedJobs .poll ();
844+ if (nextJob != null ) {
845+ startedTfJobs = addAndTrackTradefedJobs (ImmutableList .of (nextJob ));
879846 }
880847 }
881848 }
@@ -889,6 +856,25 @@ private void addMainJobs() {
889856 }
890857 }
891858
859+ private static void copyDynamicDownloadProperties (JobInfo currentJob , JobInfo nextJob ) {
860+ if (nextJob
861+ .properties ()
862+ .getBoolean (XtsConstants .IS_XTS_DYNAMIC_DOWNLOAD_ENABLED )
863+ .orElse (false )) {
864+ currentJob .tests ().getAll ().values ().stream ()
865+ .findFirst ()
866+ .ifPresent (
867+ currentTest ->
868+ nextJob
869+ .tests ()
870+ .getAll ()
871+ .values ()
872+ .forEach (
873+ nextTest ->
874+ copyTestPropertiesForDynamicDownloadJobs (currentTest , nextTest )));
875+ }
876+ }
877+
892878 /**
893879 * Adds Tradefed jobs to the session and records them in {@code runningTradefedJobs}.
894880 *
0 commit comments