• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base.test.transit;
6 
7 import androidx.annotation.Nullable;
8 
9 import org.chromium.base.Log;
10 
11 import java.util.ArrayList;
12 
13 /**
14  * A {@link Transition} into a {@link TransitStation}, either from another TransitStation or as an
15  * entry point.
16  */
17 public class Trip extends Transition {
18     private static final String TAG = "Transit";
19     private final int mId;
20 
21     @Nullable private final TransitStation mOrigin;
22     private final TransitStation mDestination;
23 
24     private static int sLastTripId;
25 
Trip(@ullable TransitStation origin, TransitStation destination, Trigger trigger)26     private Trip(@Nullable TransitStation origin, TransitStation destination, Trigger trigger) {
27         super(trigger);
28         mOrigin = origin;
29         mDestination = destination;
30         mId = ++sLastTripId;
31     }
32 
33     /**
34      * Starts a transition from a TransitStation to another (or from no TransitStation if at an
35      * entry point). Runs the transition |trigger|, and blocks until the destination TransitStation
36      * is considered ACTIVE (enter Conditions are fulfilled), the origin TransitStation is
37      * considered FINISHED (exit Conditions are fulfilled), and the Transition's conditions are
38      * fulfilled.
39      *
40      * @param origin the StationFacility to depart from, null if at an entry point.
41      * @param destination the StationFacility to arrive at.
42      * @param trigger the trigger to start the transition (e.g. clicking a view).
43      * @return the TransitStation entered.
44      * @param <T> the type of TransitStation entered.
45      */
travelSync( @ullable TransitStation origin, T destination, Trigger trigger)46     public static <T extends TransitStation> T travelSync(
47             @Nullable TransitStation origin, T destination, Trigger trigger) {
48         Trip trip = new Trip(origin, destination, trigger);
49         trip.travelSyncInternal();
50         return destination;
51     }
52 
travelSyncInternal()53     private void travelSyncInternal() {
54         embark();
55         if (mOrigin != null) {
56             Log.i(TAG, "Trip %d: Embarked at %s towards %s", mId, mOrigin, mDestination);
57         } else {
58             Log.i(TAG, "Trip %d: Starting at entry point %s", mId, mDestination);
59         }
60 
61         triggerTransition();
62         Log.i(TAG, "Trip %d: Triggered transition, waiting to arrive at %s", mId, mDestination);
63 
64         waitUntilArrival();
65         Log.i(TAG, "Trip %d: Arrived at %s", mId, mDestination);
66 
67         PublicTransitConfig.maybePauseAfterTransition(mDestination);
68     }
69 
embark()70     private void embark() {
71         if (mOrigin != null) {
72             mOrigin.setStateTransitioningFrom();
73         }
74         mDestination.setStateTransitioningTo();
75     }
76 
waitUntilArrival()77     private void waitUntilArrival() {
78         ArrayList<ConditionWaiter.ConditionWaitStatus> waitStatuses = new ArrayList<>();
79 
80         if (mOrigin != null) {
81             for (Condition condition : mOrigin.getExitConditions()) {
82                 waitStatuses.add(
83                         new ConditionWaiter.ConditionWaitStatus(
84                                 condition, ConditionWaiter.ConditionOrigin.EXIT));
85             }
86             for (Condition condition : mOrigin.getActiveFacilityExitConditions()) {
87                 waitStatuses.add(
88                         new ConditionWaiter.ConditionWaitStatus(
89                                 condition, ConditionWaiter.ConditionOrigin.EXIT));
90             }
91         }
92 
93         for (Condition condition : mDestination.getEnterConditions()) {
94             waitStatuses.add(
95                     new ConditionWaiter.ConditionWaitStatus(
96                             condition, ConditionWaiter.ConditionOrigin.ENTER));
97         }
98         for (Condition condition : getTransitionConditions()) {
99             waitStatuses.add(
100                     new ConditionWaiter.ConditionWaitStatus(
101                             condition, ConditionWaiter.ConditionOrigin.TRANSITION));
102         }
103 
104         // Throws CriteriaNotSatisfiedException if any conditions aren't met within the timeout and
105         // prints the state of all conditions. The timeout can be reduced when explicitly looking
106         // for flakiness due to tight timeouts.
107         try {
108             ConditionWaiter.waitFor(waitStatuses);
109         } catch (AssertionError e) {
110             throw new TravelException(mOrigin, mDestination, e);
111         }
112 
113         if (mOrigin != null) {
114             mOrigin.setStateFinished();
115         }
116         mDestination.setStateActive();
117         TrafficControl.notifyActiveStationChanged(mDestination);
118     }
119 }
120