• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package android.car.hiddenapitest;
18 
19 import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_IDLING;
20 import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_MOVING;
21 import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_PARKED;
22 import static android.car.drivingstate.CarDrivingStateEvent.DRIVING_STATE_UNKNOWN;
23 import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_BASELINE;
24 import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_FULLY_RESTRICTED;
25 import static android.car.drivingstate.CarUxRestrictions.UX_RESTRICTIONS_NO_VIDEO;
26 import static android.car.drivingstate.CarUxRestrictionsConfiguration.Builder.SpeedRange.MAX_SPEED;
27 import static android.car.drivingstate.CarUxRestrictionsManager.UX_RESTRICTION_MODE_BASELINE;
28 
29 import static com.google.common.truth.Truth.assertThat;
30 
31 import static org.junit.Assert.assertThrows;
32 
33 import android.car.drivingstate.CarUxRestrictions;
34 import android.car.drivingstate.CarUxRestrictionsConfiguration;
35 import android.car.drivingstate.CarUxRestrictionsConfiguration.Builder;
36 import android.car.drivingstate.CarUxRestrictionsConfiguration.DrivingStateRestrictions;
37 import android.car.extendedapitest.testbase.CarLessApiTestBase;
38 import android.os.Parcel;
39 import android.util.JsonReader;
40 import android.util.JsonWriter;
41 
42 import androidx.test.filters.SmallTest;
43 
44 import org.junit.Test;
45 
46 import java.io.ByteArrayInputStream;
47 import java.io.ByteArrayOutputStream;
48 import java.io.InputStreamReader;
49 import java.io.OutputStreamWriter;
50 import java.io.PrintWriter;
51 import java.io.StringReader;
52 
53 /**
54  * Unit test for UXR config and its subclasses.
55  */
56 @SmallTest
57 public final class CarUxRestrictionsConfigurationTest extends CarLessApiTestBase {
58 
59     private static final String UX_RESTRICTION_MODE_PASSENGER = "passenger";
60 
61     // This test verifies the expected way to build config would succeed.
62     @Test
testConstruction()63     public void testConstruction() {
64         new Builder().build();
65 
66         new Builder()
67                 .setMaxStringLength(1)
68                 .build();
69 
70         new Builder()
71                 .setUxRestrictions(DRIVING_STATE_PARKED, false, UX_RESTRICTIONS_BASELINE)
72                 .build();
73 
74         new Builder()
75                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED)
76                 .build();
77 
78         new Builder()
79                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
80                         .setDistractionOptimizationRequired(true)
81                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
82                         .setSpeedRange(new Builder.SpeedRange(0f, MAX_SPEED)))
83                 .build();
84 
85         new Builder()
86                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
87                         .setDistractionOptimizationRequired(true)
88                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
89                         .setSpeedRange(new Builder.SpeedRange(0f, 1f)))
90                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
91                         .setDistractionOptimizationRequired(true)
92                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
93                         .setSpeedRange(new Builder.SpeedRange(1f, MAX_SPEED)))
94                 .build();
95     }
96 
97     @Test
testUnspecifiedDrivingStateUsesDefaultRestriction()98     public void testUnspecifiedDrivingStateUsesDefaultRestriction() {
99         CarUxRestrictionsConfiguration config = new Builder().build();
100 
101         CarUxRestrictions parkedRestrictions = config.getUxRestrictions(DRIVING_STATE_PARKED, 0f);
102         assertThat(parkedRestrictions.isRequiresDistractionOptimization()).isTrue();
103         assertThat(parkedRestrictions.getActiveRestrictions())
104                 .isEqualTo(UX_RESTRICTIONS_FULLY_RESTRICTED);
105 
106         CarUxRestrictions movingRestrictions = config.getUxRestrictions(DRIVING_STATE_MOVING, 1f);
107         assertThat(movingRestrictions.isRequiresDistractionOptimization()).isTrue();
108         assertThat(movingRestrictions.getActiveRestrictions())
109                 .isEqualTo(UX_RESTRICTIONS_FULLY_RESTRICTED);
110     }
111 
112     @Test
testBuilderValidation_UnspecifiedStateUsesRestrictiveDefault()113     public void testBuilderValidation_UnspecifiedStateUsesRestrictiveDefault() {
114         CarUxRestrictionsConfiguration config = new Builder()
115                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED)
116                 .build();
117         assertThat(config.getUxRestrictions(DRIVING_STATE_PARKED, 0f)
118         .isRequiresDistractionOptimization()).isTrue();
119         assertThat(config.getUxRestrictions(DRIVING_STATE_IDLING, 0f)
120         .isRequiresDistractionOptimization()).isTrue();
121     }
122 
123     @Test
testBuilderValidation_twoWaysToIdentifyDisplay()124     public void testBuilderValidation_twoWaysToIdentifyDisplay() {
125         Builder builder = new Builder()
126                 .setPhysicalPort(1)
127                 .setOccupantZoneId(1)
128                 .setDisplayType(1)
129                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED);
130         assertThrows(IllegalStateException.class, () -> builder.build());
131     }
132 
133     @Test
testBuilderValidation_missingDisplayType()134     public void testBuilderValidation_missingDisplayType() {
135         Builder builder = new Builder()
136                 .setOccupantZoneId(1)
137                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED);
138         assertThrows(IllegalStateException.class, () -> builder.build());
139     }
140 
141     @Test
testBuilderValidation_missingOccupantZoneId()142     public void testBuilderValidation_missingOccupantZoneId() {
143         Builder builder = new Builder()
144                 .setDisplayType(1)
145                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED);
146         assertThrows(IllegalStateException.class, () -> builder.build());
147     }
148 
149     @Test
testBuilderValidation_invalidOccupantZoneId()150     public void testBuilderValidation_invalidOccupantZoneId() {
151         Builder builder = new Builder();
152         assertThrows(IllegalArgumentException.class, () -> builder.validateOccupantZoneId(-1));
153     }
154 
155     @Test
testBuilderValidation_invalidDisplayType()156     public void testBuilderValidation_invalidDisplayType() {
157         Builder builder = new Builder();
158         assertThrows(IllegalArgumentException.class, () -> builder.validateDisplayType(0));
159     }
160 
161     @Test
testBuilderValidation_NonMovingStateHasOneRestriction()162     public void testBuilderValidation_NonMovingStateHasOneRestriction() {
163         Builder builder = new Builder();
164         builder.setUxRestrictions(DRIVING_STATE_IDLING,
165                 true, UX_RESTRICTIONS_NO_VIDEO);
166         builder.setUxRestrictions(DRIVING_STATE_IDLING,
167                 false, UX_RESTRICTIONS_BASELINE);
168 
169         assertThrows(Exception.class, () -> builder.build());
170     }
171 
172     @Test
testBuilderValidation_PassengerModeNoSpeedRangeOverlap()173     public void testBuilderValidation_PassengerModeNoSpeedRangeOverlap() {
174         Builder builder = new Builder();
175         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
176                 .setDistractionOptimizationRequired(true)
177                 .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
178                 .setSpeedRange(new Builder.SpeedRange(1f, 2f)));
179         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
180                 .setDistractionOptimizationRequired(true)
181                 .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
182                 .setSpeedRange(new Builder.SpeedRange(1f)));
183         assertThrows(Exception.class, () -> builder.build());
184     }
185 
186     @Test
testBuilderValidation_PassengerModeCanSpecifySubsetOfSpeedRange()187     public void testBuilderValidation_PassengerModeCanSpecifySubsetOfSpeedRange() {
188         CarUxRestrictionsConfiguration config = new Builder()
189                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
190                         .setDistractionOptimizationRequired(true)
191                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
192                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
193                         .setSpeedRange(new Builder.SpeedRange(1f, 2f)))
194                 .build();
195 
196         assertThat(config.getUxRestrictions(DRIVING_STATE_MOVING, 1f, UX_RESTRICTION_MODE_PASSENGER)
197                 .isRequiresDistractionOptimization()).isTrue();
198     }
199 
200     @Test
testBuilderValidation_MultipleSpeedRange_NonZeroStart()201     public void testBuilderValidation_MultipleSpeedRange_NonZeroStart() {
202         Builder builder = new Builder();
203         builder.setUxRestrictions(DRIVING_STATE_MOVING,
204                 new Builder.SpeedRange(1, 2),
205                 true, UX_RESTRICTIONS_FULLY_RESTRICTED);
206         builder.setUxRestrictions(DRIVING_STATE_MOVING,
207                 new Builder.SpeedRange(2, MAX_SPEED),
208                 true, UX_RESTRICTIONS_FULLY_RESTRICTED);
209         assertThrows(Exception.class, () -> builder.build());
210     }
211 
212     @Test
testBuilderValidation_SpeedRange_NonZeroStart()213     public void testBuilderValidation_SpeedRange_NonZeroStart() {
214         Builder builder = new Builder();
215         builder.setUxRestrictions(DRIVING_STATE_MOVING,
216                 new Builder.SpeedRange(1, MAX_SPEED),
217                 true, UX_RESTRICTIONS_FULLY_RESTRICTED);
218         assertThrows(Exception.class, () -> builder.build());
219     }
220 
221     @Test
testBuilderValidation_SpeedRange_Overlap()222     public void testBuilderValidation_SpeedRange_Overlap() {
223         Builder builder = new Builder();
224         builder.setUxRestrictions(DRIVING_STATE_MOVING,
225                 new Builder.SpeedRange(0, 5), true,
226                 UX_RESTRICTIONS_FULLY_RESTRICTED);
227         builder.setUxRestrictions(DRIVING_STATE_MOVING,
228                 new Builder.SpeedRange(4), true,
229                 UX_RESTRICTIONS_FULLY_RESTRICTED);
230         assertThrows(Exception.class, () -> builder.build());
231     }
232 
233     @Test
testBuilderValidation_SpeedRange_Gap()234     public void testBuilderValidation_SpeedRange_Gap() {
235         Builder builder = new Builder();
236         builder.setUxRestrictions(DRIVING_STATE_MOVING,
237                 new Builder.SpeedRange(0, 5), true,
238                 UX_RESTRICTIONS_FULLY_RESTRICTED);
239         builder.setUxRestrictions(DRIVING_STATE_MOVING,
240                 new Builder.SpeedRange(8), true,
241                 UX_RESTRICTIONS_FULLY_RESTRICTED);
242         assertThrows(Exception.class, () -> builder.build());
243     }
244 
245     @Test
testBuilderValidation_NonMovingStateCannotUseSpeedRange()246     public void testBuilderValidation_NonMovingStateCannotUseSpeedRange() {
247         Builder builder = new Builder();
248         assertThrows(Exception.class, () -> builder.setUxRestrictions(DRIVING_STATE_PARKED,
249                 new Builder.SpeedRange(0, 5), true, UX_RESTRICTIONS_FULLY_RESTRICTED));
250     }
251 
252     @Test
testBuilderValidation_MultipleMovingRestrictionsShouldAllContainSpeedRange()253     public void testBuilderValidation_MultipleMovingRestrictionsShouldAllContainSpeedRange() {
254         Builder builder = new Builder();
255         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
256                 .setDistractionOptimizationRequired(true)
257                 .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED));
258         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
259                 .setDistractionOptimizationRequired(true)
260                 .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
261                 .setSpeedRange(new Builder.SpeedRange(1f)));
262         assertThrows(Exception.class, () -> builder.build());
263     }
264 
265     @Test
testSpeedRange_Construction()266     public void testSpeedRange_Construction() {
267         new Builder.SpeedRange(0f);
268         new Builder.SpeedRange(0f, 1f);
269         new Builder.SpeedRange(0f, MAX_SPEED);
270     }
271 
272     @Test
testSpeedRange_NoNegativeMin()273     public void testSpeedRange_NoNegativeMin() {
274         assertThrows(Exception.class, () -> new Builder.SpeedRange(-2f, 1f));
275     }
276 
277     @Test
testSpeedRange_NoNegativeMax()278     public void testSpeedRange_NoNegativeMax() {
279         assertThrows(Exception.class, () -> new Builder.SpeedRange(2f, -1f));
280     }
281 
282     @Test
testSpeedRange_MinCannotBeMaxSpeed()283     public void testSpeedRange_MinCannotBeMaxSpeed() {
284         assertThrows(Exception.class, () -> new Builder.SpeedRange(MAX_SPEED, 1f));
285     }
286 
287     @Test
testSpeedRange_MinGreaterThanMax()288     public void testSpeedRange_MinGreaterThanMax() {
289         assertThrows(Exception.class, () -> new Builder.SpeedRange(5f, 2f));
290     }
291 
292     @Test
testSpeedRangeComparison_DifferentMin()293     public void testSpeedRangeComparison_DifferentMin() {
294         Builder.SpeedRange s1 =
295                 new Builder.SpeedRange(1f);
296         Builder.SpeedRange s2 =
297                 new Builder.SpeedRange(2f);
298         assertThat(s1.compareTo(s2)).isLessThan(0);
299         assertThat(s2.compareTo(s1)).isGreaterThan(0);
300     }
301 
302     @Test
testSpeedRangeComparison_SameMin()303     public void testSpeedRangeComparison_SameMin() {
304         Builder.SpeedRange s1 =
305                 new Builder.SpeedRange(1f);
306         Builder.SpeedRange s2 =
307                 new Builder.SpeedRange(1f);
308         assertThat(s1.compareTo(s2)).isEqualTo(0);
309     }
310 
311     @Test
testSpeedRangeComparison_SameMinDifferentMax()312     public void testSpeedRangeComparison_SameMinDifferentMax() {
313         Builder.SpeedRange s1 =
314                 new Builder.SpeedRange(0f, 1f);
315         Builder.SpeedRange s2 =
316                 new Builder.SpeedRange(0f, 2f);
317         assertThat(s1.compareTo(s2)).isLessThan(0);
318         assertThat(s2.compareTo(s1)).isGreaterThan(0);
319     }
320 
321     @Test
testSpeedRangeComparison_MaxSpeed()322     public void testSpeedRangeComparison_MaxSpeed() {
323         Builder.SpeedRange s1 =
324                 new Builder.SpeedRange(0f, 1f);
325         Builder.SpeedRange s2 =
326                 new Builder.SpeedRange(0f);
327         assertThat(s1.compareTo(s2)).isLessThan(0);
328         assertThat(s2.compareTo(s1)).isGreaterThan(0);
329     }
330 
331     @Test
332     @SuppressWarnings("TruthSelfEquals")
testSpeedRangeEquals()333     public void testSpeedRangeEquals() {
334         Builder.SpeedRange s1, s2;
335 
336         s1 = new Builder.SpeedRange(0f);
337         assertThat(s1).isEqualTo(s1);
338 
339         s1 = new Builder.SpeedRange(1f);
340         s2 = new Builder.SpeedRange(1f);
341         assertThat(s1.compareTo(s2)).isEqualTo(0);
342         assertThat(s2).isEqualTo(s1);
343 
344         s1 = new Builder.SpeedRange(0f, 1f);
345         s2 = new Builder.SpeedRange(0f, 1f);
346         assertThat(s2).isEqualTo(s1);
347 
348         s1 = new Builder.SpeedRange(0f, MAX_SPEED);
349         s2 = new Builder.SpeedRange(0f, MAX_SPEED);
350         assertThat(s2).isEqualTo(s1);
351 
352         s1 = new Builder.SpeedRange(0f);
353         s2 = new Builder.SpeedRange(1f);
354         assertThat(s1).isNotEqualTo(s2);
355 
356         s1 = new Builder.SpeedRange(0f, 1f);
357         s2 = new Builder.SpeedRange(0f, 2f);
358         assertThat(s1).isNotEqualTo(s2);
359     }
360 
361     @Test
testJsonSerialization_DefaultConstructor()362     public void testJsonSerialization_DefaultConstructor() throws Exception {
363         CarUxRestrictionsConfiguration config =
364                 new Builder().build();
365 
366         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
367     }
368 
369     @Test
testJsonSerialization_RestrictionParameters()370     public void testJsonSerialization_RestrictionParameters() throws Exception {
371         CarUxRestrictionsConfiguration config = new Builder()
372                 .setMaxStringLength(1)
373                 .setMaxCumulativeContentItems(1)
374                 .setMaxContentDepth(1)
375                 .build();
376 
377         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
378     }
379 
380     @Test
testJsonSerialization_NonMovingStateRestrictions()381     public void testJsonSerialization_NonMovingStateRestrictions() throws Exception {
382         CarUxRestrictionsConfiguration config = new Builder()
383                 .setUxRestrictions(DRIVING_STATE_PARKED, false, UX_RESTRICTIONS_BASELINE)
384                 .build();
385 
386         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
387     }
388 
389     @Test
testJsonSerialization_MovingStateNoSpeedRange()390     public void testJsonSerialization_MovingStateNoSpeedRange() throws Exception {
391         CarUxRestrictionsConfiguration config = new Builder()
392                 .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_FULLY_RESTRICTED)
393                 .build();
394 
395         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
396     }
397 
398     @Test
testJsonSerialization_MovingStateWithSpeedRange()399     public void testJsonSerialization_MovingStateWithSpeedRange() throws Exception {
400         CarUxRestrictionsConfiguration config = new Builder()
401                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
402                         .setDistractionOptimizationRequired(true)
403                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
404                         .setSpeedRange(new Builder.SpeedRange(0f, 5f)))
405                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
406                         .setDistractionOptimizationRequired(true)
407                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
408                         .setSpeedRange(new Builder.SpeedRange(5f, MAX_SPEED)))
409                 .build();
410 
411         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
412     }
413 
414     @Test
testJsonSerialization_UxRestrictionMode()415     public void testJsonSerialization_UxRestrictionMode() throws Exception {
416         CarUxRestrictionsConfiguration config = new Builder()
417                 // Passenger mode
418                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
419                         .setDistractionOptimizationRequired(false)
420                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
421                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
422                 // Explicitly specify baseline mode
423                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
424                         .setDistractionOptimizationRequired(true)
425                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
426                         .setMode(UX_RESTRICTION_MODE_BASELINE))
427                 // Implicitly defaults to baseline mode
428                 .setUxRestrictions(DRIVING_STATE_IDLING, new DrivingStateRestrictions()
429                         .setDistractionOptimizationRequired(true)
430                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
431                 .build();
432 
433         verifyConfigThroughJsonSerialization(config, /* schemaVersion= */ 2);
434     }
435 
436     @Test
testJsonSerialization_ReadsV1()437     public void testJsonSerialization_ReadsV1() throws Exception {
438         String v1LegacyJsonFormat = "{\"physical_port\":1,\"max_content_depth\":2,"
439                 + "\"max_cumulative_content_items\":20,\"max_string_length\":21,"
440                 + "\"parked_restrictions\":[{\"req_opt\":false,\"restrictions\":0}],"
441                 + "\"idling_restrictions\":[{\"req_opt\":true,\"restrictions\":7}],"
442                 + "\"moving_restrictions\":[{\"req_opt\":true,\"restrictions\":8}],"
443                 + "\"unknown_restrictions\":[{\"req_opt\":true,\"restrictions\":511}],"
444                 + "\"passenger_parked_restrictions\":[{\"req_opt\":false,\"restrictions\":0}],"
445                 + "\"passenger_idling_restrictions\":[{\"req_opt\":true,\"restrictions\":56}],"
446                 + "\"passenger_moving_restrictions\":[{\"req_opt\":true,\"restrictions\":57}],"
447                 + "\"passenger_unknown_restrictions\":[{\"req_opt\":true,\"restrictions\":510}]}";
448         CarUxRestrictionsConfiguration expectedConfig = new Builder()
449                 .setPhysicalPort(1)
450                 .setMaxContentDepth(2)
451                 .setMaxCumulativeContentItems(20)
452                 .setMaxStringLength(21)
453                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
454                         .setDistractionOptimizationRequired(false)
455                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
456                         .setMode(UX_RESTRICTION_MODE_BASELINE))
457                 .setUxRestrictions(DRIVING_STATE_IDLING, new DrivingStateRestrictions()
458                         .setDistractionOptimizationRequired(true)
459                         .setRestrictions(7)
460                         .setMode(UX_RESTRICTION_MODE_BASELINE))
461                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
462                         .setDistractionOptimizationRequired(true)
463                         .setRestrictions(8)
464                         .setMode(UX_RESTRICTION_MODE_BASELINE))
465                 .setUxRestrictions(DRIVING_STATE_UNKNOWN, new DrivingStateRestrictions()
466                         .setDistractionOptimizationRequired(true)
467                         .setRestrictions(511)
468                         .setMode(UX_RESTRICTION_MODE_BASELINE))
469                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
470                         .setDistractionOptimizationRequired(false)
471                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
472                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
473                 .setUxRestrictions(DRIVING_STATE_IDLING, new DrivingStateRestrictions()
474                         .setDistractionOptimizationRequired(true)
475                         .setRestrictions(56)
476                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
477                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
478                         .setDistractionOptimizationRequired(true)
479                         .setRestrictions(57)
480                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
481                 .setUxRestrictions(DRIVING_STATE_UNKNOWN, new DrivingStateRestrictions()
482                         .setDistractionOptimizationRequired(true)
483                         .setRestrictions(510)
484                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
485                 .build();
486 
487         CarUxRestrictionsConfiguration deserialized = CarUxRestrictionsConfiguration.readJson(
488                 new JsonReader(new StringReader(v1LegacyJsonFormat)), /* schemaVersion= */ 1);
489         assertThat(deserialized).isEqualTo(expectedConfig);
490     }
491 
492 
493     @Test
testJsonSerialization_ReadUnsupportedVersion_ThrowsException()494     public void testJsonSerialization_ReadUnsupportedVersion_ThrowsException() throws Exception {
495         int unsupportedVersion = -1;
496         assertThrows(IllegalArgumentException.class, () -> CarUxRestrictionsConfiguration.readJson(
497                 new JsonReader(new StringReader("")), unsupportedVersion));
498     }
499 
500     @Test
testDump()501     public void testDump() {
502         CarUxRestrictionsConfiguration[] configs = new CarUxRestrictionsConfiguration[]{
503                 // Driving state with no speed range
504                 new Builder()
505                         .setUxRestrictions(DRIVING_STATE_PARKED, false, UX_RESTRICTIONS_BASELINE)
506                         .setUxRestrictions(DRIVING_STATE_IDLING, true, UX_RESTRICTIONS_NO_VIDEO)
507                         .setUxRestrictions(DRIVING_STATE_MOVING, true, UX_RESTRICTIONS_NO_VIDEO)
508                         .build(),
509                 // Parameters
510                 new Builder()
511                         .setMaxStringLength(1)
512                         .setMaxContentDepth(1)
513                         .setMaxCumulativeContentItems(1)
514                         .build(),
515                 // Driving state with single speed range
516                 new Builder()
517                         .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
518                                 .setDistractionOptimizationRequired(true)
519                                 .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
520                                 .setSpeedRange(new Builder.SpeedRange(0f)))
521                         .build(),
522                 // Driving state with multiple speed ranges
523                 new Builder()
524                         .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
525                                 .setDistractionOptimizationRequired(true)
526                                 .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
527                                 .setSpeedRange(new Builder.SpeedRange(0f, 1f)))
528                         .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
529                                 .setDistractionOptimizationRequired(true)
530                                 .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
531                                 .setSpeedRange(new Builder.SpeedRange(1f)))
532                         .build(),
533                 // Driving state with passenger mode
534                 new Builder()
535                         .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
536                                 .setDistractionOptimizationRequired(false)
537                                 .setRestrictions(UX_RESTRICTIONS_BASELINE)
538                                 .setMode(UX_RESTRICTION_MODE_PASSENGER))
539                         .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
540                                 .setDistractionOptimizationRequired(true)
541                                 .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
542                                 .setMode(UX_RESTRICTION_MODE_BASELINE))
543                         .build(),
544         };
545 
546         for (CarUxRestrictionsConfiguration config : configs) {
547             config.dump(new PrintWriter(new ByteArrayOutputStream()));
548         }
549     }
550 
551     @Test
testDumpContainsNecessaryInfo()552     public void testDumpContainsNecessaryInfo() {
553         CarUxRestrictionsConfiguration config = new Builder()
554                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
555                         .setDistractionOptimizationRequired(true)
556                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
557                         .setSpeedRange(new Builder.SpeedRange(0f, 1f)))
558                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
559                         .setDistractionOptimizationRequired(true)
560                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
561                         .setSpeedRange(new Builder.SpeedRange(1f)))
562                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
563                         .setDistractionOptimizationRequired(false)
564                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
565                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
566                 .build();
567         ByteArrayOutputStream output = new ByteArrayOutputStream();
568         try (PrintWriter writer = new PrintWriter(output)) {
569             config.dump(writer);
570         }
571 
572         String dump = new String(output.toByteArray());
573         assertThat(dump).contains("Max String length");
574         assertThat(dump).contains("Max Cumulative Content Items");
575         assertThat(dump).contains("Max Content depth");
576         assertThat(dump).contains("State:moving");
577         assertThat(dump).contains("Speed Range");
578         assertThat(dump).contains("Requires DO?");
579         assertThat(dump).contains("Restrictions");
580         assertThat(dump).contains("passenger mode");
581         assertThat(dump).contains("baseline mode");
582     }
583 
584     @Test
testSetUxRestrictions_UnspecifiedModeDefaultsToBaseline()585     public void testSetUxRestrictions_UnspecifiedModeDefaultsToBaseline() {
586         CarUxRestrictionsConfiguration config = new Builder()
587                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
588                         .setDistractionOptimizationRequired(true)
589                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
590                 .build();
591 
592         CarUxRestrictions restrictions = config.getUxRestrictions(DRIVING_STATE_PARKED, 0f);
593         assertThat(restrictions.isRequiresDistractionOptimization()).isTrue();
594         assertThat(restrictions.getActiveRestrictions()).isEqualTo(UX_RESTRICTIONS_NO_VIDEO);
595 
596         assertThat(restrictions.isSameRestrictions(
597         config.getUxRestrictions(DRIVING_STATE_PARKED, 0f, UX_RESTRICTION_MODE_BASELINE))).isTrue();
598     }
599 
600     @Test
testSetUxRestrictions_PassengerMode()601     public void testSetUxRestrictions_PassengerMode() {
602         CarUxRestrictionsConfiguration config = new Builder()
603                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
604                         .setDistractionOptimizationRequired(false)
605                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
606                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
607                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
608                         .setDistractionOptimizationRequired(true)
609                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
610                 .build();
611 
612         CarUxRestrictions passenger = config.getUxRestrictions(
613                 DRIVING_STATE_PARKED, 0f, UX_RESTRICTION_MODE_PASSENGER);
614         assertThat(passenger.isRequiresDistractionOptimization()).isFalse();
615 
616         CarUxRestrictions baseline = config.getUxRestrictions(
617                 DRIVING_STATE_PARKED, 0f, UX_RESTRICTION_MODE_BASELINE);
618         assertThat(baseline.isRequiresDistractionOptimization()).isTrue();
619         assertThat(baseline.getActiveRestrictions()).isEqualTo(UX_RESTRICTIONS_NO_VIDEO);
620     }
621 
622     @Test
testGetUxRestrictions_WithUndefinedMode_FallbackToBaseline()623     public void testGetUxRestrictions_WithUndefinedMode_FallbackToBaseline() {
624         CarUxRestrictionsConfiguration config = new Builder()
625                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
626                         .setDistractionOptimizationRequired(true)
627                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
628                 .build();
629 
630         CarUxRestrictions passenger = config.getUxRestrictions(
631                 DRIVING_STATE_PARKED, 0f, UX_RESTRICTION_MODE_PASSENGER);
632         assertThat(passenger.isRequiresDistractionOptimization()).isTrue();
633         assertThat(passenger.getActiveRestrictions()).isEqualTo(UX_RESTRICTIONS_NO_VIDEO);
634     }
635 
636     @Test
testGetUxRestrictions_MaxSpeed_SingleSpeedRange()637     public void testGetUxRestrictions_MaxSpeed_SingleSpeedRange() {
638         CarUxRestrictionsConfiguration config = new Builder()
639                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
640                         .setDistractionOptimizationRequired(true)
641                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
642                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
643                         .setSpeedRange(new Builder.SpeedRange(0f, 1f)))
644                 .build();
645 
646         CarUxRestrictions movingRestrictions = config.getUxRestrictions(DRIVING_STATE_MOVING,
647                 MAX_SPEED, UX_RESTRICTION_MODE_PASSENGER);
648         assertThat(movingRestrictions.isRequiresDistractionOptimization()).isTrue();
649         assertThat(movingRestrictions.getActiveRestrictions()).isEqualTo(
650                 UX_RESTRICTIONS_NO_VIDEO);
651     }
652 
653     @Test
testGetUxRestrictions_MaxSpeed_MultiSpeedRangesHighestClosed()654     public void testGetUxRestrictions_MaxSpeed_MultiSpeedRangesHighestClosed() {
655         Builder builder = new Builder();
656         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
657                         .setDistractionOptimizationRequired(true)
658                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
659                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
660                         .setSpeedRange(new Builder.SpeedRange(0f, 1f)));
661 
662         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
663                         .setDistractionOptimizationRequired(true)
664                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
665                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
666                         .setSpeedRange(new Builder.SpeedRange(1f, 2f)));
667 
668         CarUxRestrictionsConfiguration config = builder.build();
669 
670         CarUxRestrictions movingRestrictions = config.getUxRestrictions(DRIVING_STATE_MOVING,
671                 MAX_SPEED, UX_RESTRICTION_MODE_PASSENGER);
672         assertThat(movingRestrictions.isRequiresDistractionOptimization()).isTrue();
673         assertThat(movingRestrictions.getActiveRestrictions()).isEqualTo(
674                 UX_RESTRICTIONS_FULLY_RESTRICTED);
675     }
676 
677     @Test
testGetUxRestrictions_MaxSpeed_MultiSpeedRangesHighestOpen()678     public void testGetUxRestrictions_MaxSpeed_MultiSpeedRangesHighestOpen() {
679         Builder builder = new Builder();
680         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
681                         .setDistractionOptimizationRequired(true)
682                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
683                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
684                         .setSpeedRange(new Builder.SpeedRange(0f, 1f)));
685 
686         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
687                         .setDistractionOptimizationRequired(true)
688                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO)
689                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
690                         .setSpeedRange(new Builder.SpeedRange(1f, 2f)));
691 
692         builder.setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
693                         .setDistractionOptimizationRequired(true)
694                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
695                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
696                         .setSpeedRange(new Builder.SpeedRange(2f)));
697         CarUxRestrictionsConfiguration config = builder.build();
698 
699         CarUxRestrictions movingRestrictions = config.getUxRestrictions(DRIVING_STATE_MOVING,
700                 MAX_SPEED, UX_RESTRICTION_MODE_PASSENGER);
701         assertThat(movingRestrictions.isRequiresDistractionOptimization()).isTrue();
702         assertThat(movingRestrictions.getActiveRestrictions()).isEqualTo(
703                 UX_RESTRICTIONS_FULLY_RESTRICTED);
704     }
705 
706     @Test
testPassengerMode_GetMovingWhenNotDefined_FallbackToBaseline()707     public void testPassengerMode_GetMovingWhenNotDefined_FallbackToBaseline() {
708         CarUxRestrictionsConfiguration config = new Builder()
709                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
710                         .setDistractionOptimizationRequired(true)
711                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
712                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
713                         .setDistractionOptimizationRequired(false)
714                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
715                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
716                 .build();
717 
718         // Retrieve with passenger mode for a moving state
719         CarUxRestrictions passenger = config.getUxRestrictions(
720                 DRIVING_STATE_MOVING, 1f, UX_RESTRICTION_MODE_PASSENGER);
721         assertThat(passenger.isRequiresDistractionOptimization()).isTrue();
722         assertThat(passenger.getActiveRestrictions()).isEqualTo(UX_RESTRICTIONS_NO_VIDEO);
723     }
724 
725     @Test
testPassengerMode_GetSpeedOutsideDefinedRange_FallbackToBaseline()726     public void testPassengerMode_GetSpeedOutsideDefinedRange_FallbackToBaseline() {
727         CarUxRestrictionsConfiguration config = new Builder()
728                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
729                         .setDistractionOptimizationRequired(true)
730                         .setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
731                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
732                         .setDistractionOptimizationRequired(false)
733                         .setRestrictions(UX_RESTRICTIONS_BASELINE)
734                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
735                         .setSpeedRange(new Builder.SpeedRange(3f)))
736                 .build();
737 
738         // Retrieve at speed within passenger mode range.
739         CarUxRestrictions passenger = config.getUxRestrictions(
740                 DRIVING_STATE_MOVING, 5f, UX_RESTRICTION_MODE_PASSENGER);
741         assertThat(passenger.isRequiresDistractionOptimization()).isFalse();
742 
743         // Retrieve with passenger mode but outside speed range
744         CarUxRestrictions baseline = config.getUxRestrictions(
745                 DRIVING_STATE_MOVING, 1f, UX_RESTRICTION_MODE_PASSENGER);
746         assertThat(baseline.isRequiresDistractionOptimization()).isTrue();
747         assertThat(baseline.getActiveRestrictions()).isEqualTo(UX_RESTRICTIONS_NO_VIDEO);
748     }
749 
750     @Test
testHasSameParameters_SameParameters()751     public void testHasSameParameters_SameParameters() {
752         CarUxRestrictionsConfiguration one = new CarUxRestrictionsConfiguration.Builder()
753                 .setMaxStringLength(1)
754                 .setMaxCumulativeContentItems(1)
755                 .setMaxContentDepth(1)
756                 .build();
757 
758         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
759                 .setMaxStringLength(1)
760                 .setMaxCumulativeContentItems(1)
761                 .setMaxContentDepth(1)
762                 .build();
763 
764         assertThat(one.hasSameParameters(other)).isTrue();
765     }
766 
767     @Test
testHasSameParameters_DifferentParameters()768     public void testHasSameParameters_DifferentParameters() {
769         CarUxRestrictionsConfiguration one = new CarUxRestrictionsConfiguration.Builder()
770                 .setMaxStringLength(2)
771                 .setMaxCumulativeContentItems(1)
772                 .setMaxContentDepth(1)
773                 .build();
774 
775         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
776                 .setMaxStringLength(1)
777                 .setMaxCumulativeContentItems(1)
778                 .setMaxContentDepth(1)
779                 .build();
780 
781         assertThat(one.hasSameParameters(other)).isFalse();
782     }
783 
784     @Test
testConfigurationEquals()785     public void testConfigurationEquals() {
786         CarUxRestrictionsConfiguration one = new CarUxRestrictionsConfiguration.Builder()
787                 .setMaxStringLength(2)
788                 .setMaxCumulativeContentItems(1)
789                 .setMaxContentDepth(1)
790                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
791                 .setUxRestrictions(DRIVING_STATE_PARKED,
792                         new DrivingStateRestrictions().setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
793                 .build();
794 
795         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
796                 .setMaxStringLength(2)
797                 .setMaxCumulativeContentItems(1)
798                 .setMaxContentDepth(1)
799                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
800                 .setUxRestrictions(DRIVING_STATE_PARKED,
801                         new DrivingStateRestrictions().setRestrictions(UX_RESTRICTIONS_NO_VIDEO))
802                 .build();
803 
804         assertThat(other).isEqualTo(one);
805         assertThat(other.hashCode()).isEqualTo(one.hashCode());
806     }
807 
808     @Test
testConfigurationEquals_DifferentRestrictions()809     public void testConfigurationEquals_DifferentRestrictions() {
810         CarUxRestrictionsConfiguration one = new CarUxRestrictionsConfiguration.Builder()
811                 .setMaxStringLength(2)
812                 .setMaxCumulativeContentItems(1)
813                 .setMaxContentDepth(1)
814                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
815                 .setUxRestrictions(DRIVING_STATE_PARKED,
816                         new DrivingStateRestrictions().setRestrictions(
817                                 UX_RESTRICTIONS_FULLY_RESTRICTED))
818                 .build();
819 
820         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
821                 .setMaxStringLength(2)
822                 .setMaxCumulativeContentItems(1)
823                 .setMaxContentDepth(1)
824                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
825                 .setUxRestrictions(DRIVING_STATE_PARKED,
826                         new DrivingStateRestrictions().setRestrictions(UX_RESTRICTIONS_BASELINE))
827                 .build();
828 
829         assertThat(one.equals(other)).isFalse();
830     }
831 
832     @Test
testHasSameParameters_SameParameters_returnsTrue()833     public void testHasSameParameters_SameParameters_returnsTrue() {
834         CarUxRestrictionsConfiguration.Builder builder =
835                 new CarUxRestrictionsConfiguration.Builder()
836                         .setMaxStringLengthIfNotSet(1)
837                         .setMaxCumulativeContentItemsIfNotSet(1)
838                         .setMaxContentDepthIfNotSet(1);
839 
840         CarUxRestrictionsConfiguration one = builder.setMaxStringLengthIfNotSet(2)
841                 .setMaxCumulativeContentItemsIfNotSet(1)
842                 .setMaxContentDepthIfNotSet(1)
843                 .build();
844 
845         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
846                 .setMaxStringLength(1)
847                 .setMaxCumulativeContentItems(1)
848                 .setMaxContentDepth(1)
849                 .build();
850 
851         assertThat(one.hasSameParameters(other)).isTrue();
852     }
853 
854     @Test
testHasSameParameters_DifferentParameters_returnsFalse()855     public void testHasSameParameters_DifferentParameters_returnsFalse() {
856         CarUxRestrictionsConfiguration.Builder builder =
857                 new CarUxRestrictionsConfiguration.Builder()
858                         .setMaxStringLengthIfNotSet(2)
859                         .setMaxCumulativeContentItemsIfNotSet(1)
860                         .setMaxContentDepthIfNotSet(1);
861 
862         CarUxRestrictionsConfiguration one = builder.setMaxStringLengthIfNotSet(1)
863                 .setMaxCumulativeContentItemsIfNotSet(1)
864                 .setMaxContentDepthIfNotSet(1)
865                 .build();
866 
867         CarUxRestrictionsConfiguration other = new CarUxRestrictionsConfiguration.Builder()
868                 .setMaxStringLength(1)
869                 .setMaxCumulativeContentItems(1)
870                 .setMaxContentDepth(1)
871                 .build();
872 
873         assertThat(one.hasSameParameters(other)).isFalse();
874     }
875 
876     @Test
testParcelableConfiguration()877     public void testParcelableConfiguration() {
878         CarUxRestrictionsConfiguration config = new CarUxRestrictionsConfiguration.Builder()
879                 .setPhysicalPort(1)
880                 .setMaxStringLength(1)
881                 .setMaxCumulativeContentItems(1)
882                 .setMaxContentDepth(1)
883                 .setUxRestrictions(DRIVING_STATE_PARKED,
884                         new DrivingStateRestrictions().setRestrictions(
885                                 UX_RESTRICTIONS_FULLY_RESTRICTED))
886                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
887                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
888                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
889                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
890                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
891                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
892                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
893                         .setSpeedRange(new Builder.SpeedRange(0f, 5f)))
894                 .build();
895         Parcel parcel = Parcel.obtain();
896         try {
897             config.writeToParcel(parcel, 0);
898 
899             // Reset parcel data position for reading.
900             parcel.setDataPosition(0);
901 
902             CarUxRestrictionsConfiguration deserialized =
903                     CarUxRestrictionsConfiguration.CREATOR.createFromParcel(parcel);
904             assertThat(config).isEqualTo(deserialized);
905         } finally {
906             parcel.recycle();
907         }
908     }
909 
910     @Test
testParcelableConfiguration_displayConfig()911     public void testParcelableConfiguration_displayConfig() {
912         CarUxRestrictionsConfiguration config = new CarUxRestrictionsConfiguration.Builder()
913                 .setOccupantZoneId(1)
914                 .setDisplayType(1)
915                 .setMaxStringLength(1)
916                 .setMaxCumulativeContentItems(1)
917                 .setMaxContentDepth(1)
918                 .setUxRestrictions(DRIVING_STATE_PARKED,
919                         new DrivingStateRestrictions().setRestrictions(
920                                 UX_RESTRICTIONS_FULLY_RESTRICTED))
921                 .setUxRestrictions(DRIVING_STATE_PARKED, new DrivingStateRestrictions()
922                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
923                         .setMode(UX_RESTRICTION_MODE_PASSENGER))
924                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
925                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions()
926                         .setRestrictions(UX_RESTRICTIONS_FULLY_RESTRICTED)
927                         .setMode(UX_RESTRICTION_MODE_PASSENGER)
928                         .setSpeedRange(new Builder.SpeedRange(0f, 5f)))
929                 .build();
930         Parcel parcel = Parcel.obtain();
931         try {
932             config.writeToParcel(parcel, 0);
933 
934             // Reset parcel data position for reading.
935             parcel.setDataPosition(0);
936 
937             CarUxRestrictionsConfiguration deserialized =
938                     CarUxRestrictionsConfiguration.CREATOR.createFromParcel(parcel);
939             expectWithMessage("UxR config with display config serialize/deserialize")
940                     .that(config)
941                     .isEqualTo(deserialized);
942         } finally {
943             parcel.recycle();
944         }
945     }
946 
947     @Test
testParcelableConfiguration_serializeNullPhysicalPort()948     public void testParcelableConfiguration_serializeNullPhysicalPort() {
949         // Not setting physical port leaves it null.
950         CarUxRestrictionsConfiguration config = new CarUxRestrictionsConfiguration.Builder()
951                 .setMaxStringLength(1)
952                 .setMaxCumulativeContentItems(1)
953                 .setMaxContentDepth(1)
954                 .setUxRestrictions(DRIVING_STATE_MOVING, new DrivingStateRestrictions())
955                 .setUxRestrictions(DRIVING_STATE_PARKED,
956                         new DrivingStateRestrictions().setRestrictions(
957                                 UX_RESTRICTIONS_FULLY_RESTRICTED))
958                 .build();
959         Parcel parcel = Parcel.obtain();
960         try {
961             config.writeToParcel(parcel, 0);
962 
963             // Reset parcel data position for reading.
964             parcel.setDataPosition(0);
965 
966             CarUxRestrictionsConfiguration deserialized =
967                     CarUxRestrictionsConfiguration.CREATOR.createFromParcel(parcel);
968             assertThat(config).isEqualTo(deserialized);
969             assertThat(deserialized.getPhysicalPort()).isNull();
970         } finally {
971             parcel.recycle();
972         }
973     }
974 
975     /**
976      * Writes input config as json, then reads a config out of json.
977      * Asserts the deserialized config is the same as input.
978      */
verifyConfigThroughJsonSerialization(CarUxRestrictionsConfiguration config, int schemaVersion)979     private void verifyConfigThroughJsonSerialization(CarUxRestrictionsConfiguration config,
980             int schemaVersion) throws Exception {
981         ByteArrayOutputStream out = new ByteArrayOutputStream();
982         try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(out))) {
983             config.writeJson(writer);
984         }
985 
986         ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
987         try (JsonReader reader = new JsonReader(new InputStreamReader(in))) {
988             CarUxRestrictionsConfiguration deserialized = CarUxRestrictionsConfiguration.readJson(
989                     reader, schemaVersion);
990             assertThat(deserialized).isEqualTo(config);
991         }
992     }
993 }
994