1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.adservices.shared.meta_testing;
17 
18 import static com.android.adservices.shared.meta_testing.CommonDescriptions.newTestMethodForClassRule;
19 import static com.android.adservices.shared.testing.AndroidSdk.SC;
20 import static com.android.adservices.shared.testing.AndroidSdk.SC_V2;
21 import static com.android.adservices.shared.testing.SdkSandbox.State.DISABLED;
22 import static com.android.adservices.shared.testing.SdkSandbox.State.ENABLED;
23 import static com.android.adservices.shared.testing.device.DeviceConfig.SyncDisabledModeForTest.DISABLED_SOMEHOW;
24 import static com.android.adservices.shared.testing.device.DeviceConfig.SyncDisabledModeForTest.NONE;
25 import static com.android.adservices.shared.testing.device.DeviceConfig.SyncDisabledModeForTest.PERSISTENT;
26 import static com.android.adservices.shared.testing.device.DeviceConfig.SyncDisabledModeForTest.UNTIL_REBOOT;
27 
28 import static com.google.common.truth.Truth.assertWithMessage;
29 
30 import static org.junit.Assume.assumeFalse;
31 
32 import com.android.adservices.shared.meta_testing.CommonDescriptions.AClassDisablesDeviceConfigUntilReboot;
33 import com.android.adservices.shared.meta_testing.CommonDescriptions.AClassDisablesSdkSandbox;
34 import com.android.adservices.shared.meta_testing.CommonDescriptions.AClassEnablesSdkSandbox;
35 import com.android.adservices.shared.meta_testing.CommonDescriptions.AClassHasNoNothingAtAll;
36 import com.android.adservices.shared.meta_testing.CommonDescriptions.ASubClassDisablesDeviceConfigUntilRebootAndAlsoEnablesSdkSandbox;
37 import com.android.adservices.shared.meta_testing.CommonDescriptions.ASubClassEnablesSdkSandboxAndAlsoDisablesDeviceConfigUntilReboot;
38 import com.android.adservices.shared.meta_testing.CommonDescriptions.ATypicalSubclass;
39 import com.android.adservices.shared.meta_testing.CommonDescriptions.ATypicalSubclassThatImplementsAnInterfaceThatEnablesSdkSandbox;
40 import com.android.adservices.shared.testing.DynamicLogger;
41 import com.android.adservices.shared.testing.Logger;
42 import com.android.adservices.shared.testing.SdkSandbox;
43 import com.android.adservices.shared.testing.SetSdkSandboxStateAction;
44 import com.android.adservices.shared.testing.annotations.RequiresSdkLevelAtLeastT;
45 import com.android.adservices.shared.testing.annotations.RequiresSdkRange;
46 import com.android.adservices.shared.testing.device.DeviceConfig;
47 import com.android.adservices.shared.testing.device.DeviceConfig.SyncDisabledModeForTest;
48 import com.android.adservices.shared.testing.flags.AbstractFlagsPreparerClassRule;
49 import com.android.adservices.shared.testing.flags.SetSyncModeAction;
50 
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Test;
54 import org.junit.runner.Description;
55 
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.List;
59 import java.util.concurrent.atomic.AtomicReference;
60 
61 // TODO(b/347083260): missing AdservicesHostSideFlagsPreparerClassRuleIntegrationTest
62 /**
63  * Integration test for {@link SdkSandbox} implementations.
64  *
65  * <p>It executes the commands and checks the result; it's needed to make sure {@code cmd} and
66  * {@code dumpsys} output are properly parsed.
67  *
68  * @param <R> concrete rule type
69  */
70 public abstract class AbstractFlagsPreparerClassRuleIntegrationTestCase<
71                 R extends AbstractFlagsPreparerClassRule<R>>
72         extends IntegrationTestCase {
73 
74     private final AtomicReference<SyncDisabledModeForTest> mSyncModeOnTest =
75             new AtomicReference<>();
76     private final AtomicReference<SdkSandbox.State> mSdkSandboxStateOnTest =
77             new AtomicReference<>();
78 
79     private final List<Object> mCalls = new ArrayList<>();
80     // mCalls is used to keep track of the relevant calls made to the objects below
81     private final MyDeviceConfigWrapper mDeviceConfig = new MyDeviceConfigWrapper();
82     private final SdkSandboxWrapper mSdkSandbox = new MySdkSandboxWrapper();
83 
84     // mSetupCalls contains the calls made to prepare the device for the test
85     private final List<Object> mSetupCalls = new ArrayList<>();
86 
87     private R mRule;
88 
89     private SyncDisabledModeForTest mSyncModeBefore;
90     private SdkSandbox.State mSdkSandboxStateBefore;
91 
92     private final SimpleStatement mStatement =
93             new SimpleStatement()
94                     .onEvaluate(
95                             () -> {
96                                 SyncDisabledModeForTest syncDisabledMode =
97                                         mDeviceConfig.getSyncDisabledMode();
98                                 SdkSandbox.State state = mSdkSandbox.getState();
99                                 mLog.d(
100                                         "on test: deviceConfig.syncMode=%s, sdkSandbox.state=%s",
101                                         syncDisabledMode, state);
102                                 mSyncModeOnTest.set(syncDisabledMode);
103                                 mSdkSandboxStateOnTest.set(state);
104                             });
105 
106     /**
107      * Creates a new, side-specific instance of the rule.
108      *
109      * @param sdkSandboxWrapper used to inject the real {@link SdkSandbox} used by the rule
110      * @param deviceConfigWrapper used to inject the real {@link DeviceConfig} used by the rule
111      * @return new instance
112      */
newRule( SdkSandboxWrapper sdkSandboxWrapper, DeviceConfigWrapper deviceConfigWrapper)113     protected abstract R newRule(
114             SdkSandboxWrapper sdkSandboxWrapper, DeviceConfigWrapper deviceConfigWrapper);
115 
116     @Before
setFixtures()117     public final void setFixtures() {
118         mRule = newRule(mSdkSandbox, mDeviceConfig);
119         if (mRule == null) {
120             assertWithMessage("newRule() returned null").fail();
121         }
122         mSyncModeBefore = mDeviceConfig.getSyncDisabledMode();
123         mSdkSandboxStateBefore = mSdkSandbox.getState();
124         mLog.d(
125                 "setFixtures(): deviceConfig.syncMode=%s, sdkSandbox.state=%s",
126                 mSyncModeBefore, mSdkSandboxStateBefore);
127     }
128 
129     @After
restoreState()130     public final void restoreState() {
131         try {
132             if (mSyncModeBefore.isSettable()) {
133                 mDeviceConfig.setSyncDisabledMode(mSyncModeBefore);
134             }
135         } finally {
136             if (mSdkSandboxStateBefore.isSettable()) {
137                 mSdkSandbox.setState(mSdkSandboxStateBefore);
138             }
139         }
140     }
141 
142     @Test
testAnnotationLessRule()143     public final void testAnnotationLessRule() throws Throwable {
144         Description test = newTestMethodForClassRule(AClassHasNoNothingAtAll.class);
145 
146         mRule.apply(mStatement, test).evaluate();
147 
148         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
149                 .that(mSyncModeOnTest.get())
150                 .isEqualTo(mSyncModeBefore);
151         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
152                 .that(mDeviceConfig.getSyncDisabledMode())
153                 .isEqualTo(mSyncModeBefore);
154         expect.withMessage("sdkSandbox.getState() on test")
155                 .that(mSdkSandboxStateOnTest.get())
156                 .isEqualTo(mSdkSandboxStateBefore);
157         expect.withMessage("sdkSandbox.getState() after test")
158                 .that(mSdkSandbox.getState())
159                 .isEqualTo(mSdkSandboxStateBefore);
160 
161         expectCalls();
162     }
163 
164     @Test
testMethodAnnotation_setSdkSandboxStateEnabledAnnotation()165     public final void testMethodAnnotation_setSdkSandboxStateEnabledAnnotation() throws Throwable {
166         setSdkSandboxState(DISABLED);
167 
168         Description test =
169                 newTestMethodForClassRule(
170                         AClassHasNoNothingAtAll.class,
171                         // Should be ignored - rule only uses annotations from types
172                         new SetSdkSandboxStateEnabledAnnotation(true));
173 
174         mRule.apply(mStatement, test).evaluate();
175 
176         expect.withMessage("sdkSandbox.getState() on test")
177                 .that(mSdkSandboxStateOnTest.get())
178                 .isEqualTo(DISABLED);
179         expect.withMessage("sdkSandbox.getState() after test")
180                 .that(mSdkSandbox.getState())
181                 .isEqualTo(DISABLED);
182 
183         expectCalls();
184     }
185 
186     @Test
testMethodAnnotation_setSdkSandboxStateDisabledAnnotation()187     public final void testMethodAnnotation_setSdkSandboxStateDisabledAnnotation() throws Throwable {
188         setSdkSandboxState(ENABLED);
189 
190         Description test =
191                 newTestMethodForClassRule(
192                         AClassHasNoNothingAtAll.class,
193                         // Should be ignored - rule only uses annotations from types
194                         new SetSdkSandboxStateEnabledAnnotation(false));
195 
196         mRule.apply(mStatement, test).evaluate();
197 
198         expect.withMessage("sdkSandbox.getState() on test")
199                 .that(mSdkSandboxStateOnTest.get())
200                 .isEqualTo(ENABLED);
201         expect.withMessage("sdkSandbox.getState() after test")
202                 .that(mSdkSandbox.getState())
203                 .isEqualTo(ENABLED);
204 
205         expectCalls();
206     }
207 
208     @Test
testMethodAnnotation_setSyncDisabledModeForTestAnnotation()209     public final void testMethodAnnotation_setSyncDisabledModeForTestAnnotation() throws Throwable {
210         setSyncMode(NONE);
211         Description test =
212                 newTestMethodForClassRule(
213                         AClassHasNoNothingAtAll.class,
214                         // Should be ignored - rule only uses annotations from types
215                         new SetSyncDisabledModeForTestAnnotation(PERSISTENT));
216 
217         mRule.apply(mStatement, test).evaluate();
218 
219         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
220                 .that(mSyncModeOnTest.get())
221                 .isEqualTo(NONE);
222         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
223                 .that(mDeviceConfig.getSyncDisabledMode())
224                 .isEqualTo(NONE);
225 
226         expectCalls();
227     }
228 
229 
230     @Test
testClassAnnotation_setSdkSandboxStateEnabled()231     public final void testClassAnnotation_setSdkSandboxStateEnabled() throws Throwable {
232         setSdkSandboxState(DISABLED);
233         Description test = newTestMethodForClassRule(AClassEnablesSdkSandbox.class);
234 
235         mRule.apply(mStatement, test).evaluate();
236 
237         expect.withMessage("sdkSandbox.getState() on test")
238                 .that(mSdkSandboxStateOnTest.get())
239                 .isEqualTo(ENABLED);
240         expect.withMessage("sdkSandbox.getState() after test")
241                 .that(mSdkSandbox.getState())
242                 .isEqualTo(mSdkSandboxStateBefore);
243 
244         expectCalls(ENABLED, mSdkSandboxStateBefore);
245     }
246 
247     @Test
testClassAnnotation_setSdkSandboxStateDisabled()248     public final void testClassAnnotation_setSdkSandboxStateDisabled() throws Throwable {
249         setSdkSandboxState(ENABLED);
250         Description test = newTestMethodForClassRule(AClassDisablesSdkSandbox.class);
251 
252         mRule.apply(mStatement, test).evaluate();
253 
254         expect.withMessage("sdkSandbox.getState() on test")
255                 .that(mSdkSandboxStateOnTest.get())
256                 .isEqualTo(DISABLED);
257         expect.withMessage("sdkSandbox.getState() after test")
258                 .that(mSdkSandbox.getState())
259                 .isEqualTo(ENABLED);
260 
261         expectCalls(DISABLED, ENABLED);
262     }
263 
264     @Test
265     @RequiresSdkRange(atLeast = SC, atMost = SC_V2, reason = "disabled type is unknown on S")
testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot_S()266     public final void testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot_S()
267             throws Throwable {
268         testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot(DISABLED_SOMEHOW);
269     }
270 
271     @Test
272     @RequiresSdkLevelAtLeastT(reason = "disabled type is unknown on S")
testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot_TPlus()273     public final void testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot_TPlus()
274             throws Throwable {
275         testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot(UNTIL_REBOOT);
276     }
277 
testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot( SyncDisabledModeForTest expectedModeAfterSet)278     private void testClassAnnotation_setSyncDisabledModeForTestAnnotation_untilReboot(
279             SyncDisabledModeForTest expectedModeAfterSet) throws Throwable {
280         setSyncMode(NONE);
281         Description test = newTestMethodForClassRule(AClassDisablesDeviceConfigUntilReboot.class);
282 
283         mRule.apply(mStatement, test).evaluate();
284 
285         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
286                 .that(mSyncModeOnTest.get())
287                 .isEqualTo(expectedModeAfterSet);
288         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
289                 .that(mDeviceConfig.getSyncDisabledMode())
290                 .isEqualTo(NONE);
291 
292         expectCalls(UNTIL_REBOOT, NONE);
293     }
294 
295     @Test
296     public final void
testClassAndMethodAnnotation_setSyncDisabledModeForTestAnnotation_untilRebootThenNone()297             testClassAndMethodAnnotation_setSyncDisabledModeForTestAnnotation_untilRebootThenNone()
298                     throws Throwable {
299         setSyncMode(NONE);
300         Description test =
301                 newTestMethodForClassRule(
302                         AClassDisablesDeviceConfigUntilReboot.class,
303                         // should be ignored
304                         new SetSyncDisabledModeForTestAnnotation(PERSISTENT));
305 
306         mRule.apply(mStatement, test).evaluate();
307 
308         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
309                 .that(mSyncModeOnTest.get())
310                 .isEqualTo(UNTIL_REBOOT);
311         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
312                 .that(mDeviceConfig.getSyncDisabledMode())
313                 .isEqualTo(NONE);
314 
315         expectCalls(UNTIL_REBOOT, NONE);
316     }
317 
318     @Test
testAnnotationsFromSubclassAreExecutedFirstAndInOrder_sdkSandboxFirst()319     public final void testAnnotationsFromSubclassAreExecutedFirstAndInOrder_sdkSandboxFirst()
320             throws Throwable {
321         setSyncMode(PERSISTENT);
322         setSdkSandboxState(DISABLED);
323         Description test =
324                 newTestMethodForClassRule(
325                         ASubClassEnablesSdkSandboxAndAlsoDisablesDeviceConfigUntilReboot.class);
326 
327         mRule.apply(mStatement, test).evaluate();
328 
329         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
330                 .that(mSyncModeOnTest.get())
331                 .isEqualTo(UNTIL_REBOOT);
332         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
333                 .that(mDeviceConfig.getSyncDisabledMode())
334                 .isEqualTo(PERSISTENT);
335 
336         expect.withMessage("sdkSandbox.getState() on test")
337                 .that(mSdkSandboxStateOnTest.get())
338                 .isEqualTo(ENABLED);
339         expect.withMessage("sdkSandbox.getState() after test")
340                 .that(mSdkSandbox.getState())
341                 .isEqualTo(DISABLED);
342 
343         expectCalls(ENABLED, UNTIL_REBOOT, PERSISTENT, DISABLED);
344     }
345 
346     @Test
testAnnotationsFromSubclassAreExecutedFirstAndInOrder_deviceConfigFirst()347     public final void testAnnotationsFromSubclassAreExecutedFirstAndInOrder_deviceConfigFirst()
348             throws Throwable {
349         setSyncMode(PERSISTENT);
350         setSdkSandboxState(DISABLED);
351         Description test =
352                 newTestMethodForClassRule(
353                         ASubClassDisablesDeviceConfigUntilRebootAndAlsoEnablesSdkSandbox.class);
354 
355         mRule.apply(mStatement, test).evaluate();
356 
357         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
358                 .that(mSyncModeOnTest.get())
359                 .isEqualTo(UNTIL_REBOOT);
360         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
361                 .that(mDeviceConfig.getSyncDisabledMode())
362                 .isEqualTo(PERSISTENT);
363 
364         expect.withMessage("sdkSandbox.getState() on test")
365                 .that(mSdkSandboxStateOnTest.get())
366                 .isEqualTo(ENABLED);
367         expect.withMessage("sdkSandbox.getState() after test")
368                 .that(mSdkSandbox.getState())
369                 .isEqualTo(DISABLED);
370 
371         // NOTE: ideally it should follow the annotations order and be:
372         // UNTIL_REBOOT, ENABLED, DISABLED, PERSISTENT);
373         // but we cannot guarantee the order (see comment on AbstractFlagsPreparerClassRule)
374         expectCalls(ENABLED, UNTIL_REBOOT, PERSISTENT, DISABLED);
375     }
376 
377     @Test
378     public final void
testAnnotationsFromSubclassWithInterfaceAreExecutedFirstAndInOrder_sdkSandboxFirst()379             testAnnotationsFromSubclassWithInterfaceAreExecutedFirstAndInOrder_sdkSandboxFirst()
380                     throws Throwable {
381         setSyncMode(PERSISTENT);
382         setSdkSandboxState(DISABLED);
383         Description test =
384                 newTestMethodForClassRule(
385                         ASubClassEnablesSdkSandboxAndAlsoDisablesDeviceConfigUntilReboot.class);
386 
387         mRule.apply(mStatement, test).evaluate();
388 
389         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
390                 .that(mSyncModeOnTest.get())
391                 .isEqualTo(UNTIL_REBOOT);
392         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
393                 .that(mDeviceConfig.getSyncDisabledMode())
394                 .isEqualTo(PERSISTENT);
395 
396         expect.withMessage("sdkSandbox.getState() on test")
397                 .that(mSdkSandboxStateOnTest.get())
398                 .isEqualTo(ENABLED);
399         expect.withMessage("sdkSandbox.getState() after test")
400                 .that(mSdkSandbox.getState())
401                 .isEqualTo(DISABLED);
402 
403         expectCalls(ENABLED, UNTIL_REBOOT, PERSISTENT, DISABLED);
404     }
405 
406     @Test
testAnnotationsFromATypicalSubclass()407     public final void testAnnotationsFromATypicalSubclass() throws Throwable {
408         setSyncMode(NONE);
409 
410         // ATypicalSubclass doesn't declare any annotation, but its superclass sets sync mode as
411         // persistent
412         Description test = newTestMethodForClassRule(ATypicalSubclass.class);
413 
414         mRule.apply(mStatement, test).evaluate();
415 
416         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
417                 .that(mSyncModeOnTest.get())
418                 .isEqualTo(PERSISTENT);
419         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
420                 .that(mDeviceConfig.getSyncDisabledMode())
421                 .isEqualTo(NONE);
422 
423         expect.withMessage("sdkSandbox.getState() on test")
424                 .that(mSdkSandboxStateOnTest.get())
425                 .isEqualTo(mSdkSandboxStateBefore);
426         expect.withMessage("sdkSandbox.getState() after test")
427                 .that(mSdkSandbox.getState())
428                 .isEqualTo(mSdkSandboxStateBefore);
429 
430         expectCalls(PERSISTENT, NONE);
431     }
432 
433     @Test
434     public final void
testAnnotationsFromATypicalSubclassThatImplementsAnInterfaceThatEnablesSdkSandbox()435             testAnnotationsFromATypicalSubclassThatImplementsAnInterfaceThatEnablesSdkSandbox()
436                     throws Throwable {
437         setSyncMode(NONE);
438         setSdkSandboxState(DISABLED);
439 
440         // ATypicalSubclassThatImplementsAnInterfaceThatEnablesSdkSandbox doesn't declare any
441         // annotation, but its superclass sets sync mode as persistent and the interface enables
442         // SdkSandbox
443         Description test =
444                 newTestMethodForClassRule(
445                         ATypicalSubclassThatImplementsAnInterfaceThatEnablesSdkSandbox.class);
446 
447         mRule.apply(mStatement, test).evaluate();
448 
449         expect.withMessage("deviceConfig.getSyncDisabledMode() on test")
450                 .that(mSyncModeOnTest.get())
451                 .isEqualTo(PERSISTENT);
452         expect.withMessage("deviceConfig.getSyncDisabledMode() after test")
453                 .that(mDeviceConfig.getSyncDisabledMode())
454                 .isEqualTo(NONE);
455 
456         expect.withMessage("sdkSandbox.getState() on test")
457                 .that(mSdkSandboxStateOnTest.get())
458                 .isEqualTo(ENABLED);
459         expect.withMessage("sdkSandbox.getState() after test")
460                 .that(mSdkSandbox.getState())
461                 .isEqualTo(DISABLED);
462 
463         expectCalls(ENABLED, PERSISTENT, NONE, DISABLED);
464     }
465 
466     /**
467      * Asserts calls received by the test, in sequence.
468      *
469      * <p>Usually called with an even number of calls - the calls from execute() and the calls from
470      * revert()
471      */
expectCalls(Object... calls)472     private void expectCalls(Object... calls) {
473         List<Object> expectedCalls = new ArrayList<>(mSetupCalls);
474         Arrays.stream(calls).forEach(call -> expectedCalls.add(call));
475 
476         expect.withMessage("calls").that(mCalls).containsExactlyElementsIn(expectedCalls).inOrder();
477     }
478 
479     public final class MyDeviceConfigWrapper extends DeviceConfigWrapper {
480 
MyDeviceConfigWrapper()481         public MyDeviceConfigWrapper() {
482             super(new Logger(DynamicLogger.getInstance(), "DeviceConfigWrapper"));
483         }
484 
485         @Override
setSyncDisabledMode(SyncDisabledModeForTest mode)486         public MyDeviceConfigWrapper setSyncDisabledMode(SyncDisabledModeForTest mode) {
487             mCalls.add(mode);
488             super.setSyncDisabledMode(mode);
489             return this;
490         }
491     }
492 
493     public final class MySdkSandboxWrapper extends SdkSandboxWrapper {
494 
MySdkSandboxWrapper()495         public MySdkSandboxWrapper() {
496             super(new Logger(DynamicLogger.getInstance(), "SdkSandboxWrapper"));
497         }
498 
499         @Override
setState(State state)500         public MySdkSandboxWrapper setState(State state) {
501             mCalls.add(state);
502             super.setState(state);
503             return this;
504         }
505     }
506 
setSyncMode(SyncDisabledModeForTest mode)507     private void setSyncMode(SyncDisabledModeForTest mode) throws Exception {
508         assumeDeviceConfigSyncModeIsSupported();
509         var action = new SetSyncModeAction(mFakeLogger, mDeviceConfig, mode);
510         if (action.execute()) {
511             mSetupCalls.add(mode);
512         }
513     }
514 
setSdkSandboxState(SdkSandbox.State state)515     private void setSdkSandboxState(SdkSandbox.State state) throws Exception {
516         assumeSdkSandboxStateIsSupported();
517         var action = new SetSdkSandboxStateAction(mFakeLogger, mSdkSandbox, state);
518         if (action.execute()) {
519             mSetupCalls.add(state);
520         }
521     }
522 
assumeDeviceConfigSyncModeIsSupported()523     private void assumeDeviceConfigSyncModeIsSupported() {
524         assumeFalse(
525                 "initial device_config mode is " + mSyncModeBefore,
526                 SyncDisabledModeForTest.UNSUPPORTED.equals(mSyncModeBefore));
527     }
528 
assumeSdkSandboxStateIsSupported()529     private void assumeSdkSandboxStateIsSupported() {
530         assumeFalse(
531                 "initial sdk_sandbox state is " + mSdkSandboxStateBefore,
532                 SdkSandbox.State.UNSUPPORTED.equals(mSdkSandboxStateBefore));
533     }
534 }
535