1 /* 2 * Copyright (C) 2022 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 com.android.car.internal.property; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertThrows; 22 import static org.mockito.Mockito.mock; 23 import static org.mockito.Mockito.when; 24 25 import android.car.VehicleAreaType; 26 import android.car.feature.FeatureFlags; 27 import android.car.hardware.CarPropertyConfig; 28 import android.car.hardware.property.AreaIdConfig; 29 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.mockito.junit.MockitoJUnitRunner; 33 34 import java.util.List; 35 36 @RunWith(MockitoJUnitRunner.class) 37 public final class InputSanitizationUtilsUnitTest { 38 private static final int PROPERTY_ID = 123; 39 private static final float DEFAULT_UPDATE_RATE_HZ = 55.5f; 40 private static final float MIN_UPDATE_RATE_HZ = 11.11f; 41 private static final float MAX_UPDATE_RATE_HZ = 100.3f; 42 private static final CarPropertyConfig.Builder<Integer> CAR_PROPERTY_CONFIG_BUILDER = 43 CarPropertyConfig.newBuilder( 44 Integer.class, PROPERTY_ID, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL); 45 46 @Test sanitizeUpdateRateHz_returnsZeroForStaticProperties()47 public void sanitizeUpdateRateHz_returnsZeroForStaticProperties() { 48 assertThat( 49 InputSanitizationUtils.sanitizeUpdateRateHz( 50 CAR_PROPERTY_CONFIG_BUILDER 51 .setChangeMode( 52 CarPropertyConfig 53 .VEHICLE_PROPERTY_CHANGE_MODE_STATIC) 54 .build(), 55 DEFAULT_UPDATE_RATE_HZ)) 56 .isEqualTo(0); 57 } 58 59 @Test sanitizeUpdateRateHz_returnsZeroForOnChangeProperties()60 public void sanitizeUpdateRateHz_returnsZeroForOnChangeProperties() { 61 assertThat( 62 InputSanitizationUtils.sanitizeUpdateRateHz( 63 CAR_PROPERTY_CONFIG_BUILDER 64 .setChangeMode( 65 CarPropertyConfig 66 .VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE) 67 .build(), 68 DEFAULT_UPDATE_RATE_HZ)) 69 .isEqualTo(0); 70 } 71 72 @Test sanitizeUpdateRateHz_returnsMaxUpdateRateHzIfOver()73 public void sanitizeUpdateRateHz_returnsMaxUpdateRateHzIfOver() { 74 assertThat( 75 InputSanitizationUtils.sanitizeUpdateRateHz( 76 CAR_PROPERTY_CONFIG_BUILDER 77 .setChangeMode( 78 CarPropertyConfig 79 .VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) 80 .setMinSampleRate(MIN_UPDATE_RATE_HZ) 81 .setMaxSampleRate(MAX_UPDATE_RATE_HZ) 82 .build(), 83 MAX_UPDATE_RATE_HZ + 1)) 84 .isEqualTo(MAX_UPDATE_RATE_HZ); 85 } 86 87 @Test sanitizeUpdateRateHz_returnsMinUpdateRateHzIfOver()88 public void sanitizeUpdateRateHz_returnsMinUpdateRateHzIfOver() { 89 assertThat( 90 InputSanitizationUtils.sanitizeUpdateRateHz( 91 CAR_PROPERTY_CONFIG_BUILDER 92 .setChangeMode( 93 CarPropertyConfig 94 .VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) 95 .setMinSampleRate(MIN_UPDATE_RATE_HZ) 96 .setMaxSampleRate(MAX_UPDATE_RATE_HZ) 97 .build(), 98 MIN_UPDATE_RATE_HZ - 1)) 99 .isEqualTo(MIN_UPDATE_RATE_HZ); 100 } 101 102 @Test sanitizeUpdateRateHz_returnsDefaultUpdateRateHz()103 public void sanitizeUpdateRateHz_returnsDefaultUpdateRateHz() { 104 assertThat( 105 InputSanitizationUtils.sanitizeUpdateRateHz( 106 CAR_PROPERTY_CONFIG_BUILDER 107 .setChangeMode( 108 CarPropertyConfig 109 .VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) 110 .setMinSampleRate(MIN_UPDATE_RATE_HZ) 111 .setMaxSampleRate(MAX_UPDATE_RATE_HZ) 112 .build(), 113 DEFAULT_UPDATE_RATE_HZ)) 114 .isEqualTo(DEFAULT_UPDATE_RATE_HZ); 115 } 116 117 @Test testIsVurAllowed()118 public void testIsVurAllowed() { 119 CarPropertyConfig config = mock(CarPropertyConfig.class); 120 when(config.getChangeMode()).thenReturn( 121 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS); 122 FeatureFlags featureFlags = mock(FeatureFlags.class); 123 when(featureFlags.variableUpdateRate()).thenReturn(true); 124 125 assertThat(InputSanitizationUtils.isVurAllowed(featureFlags, config)).isTrue(); 126 } 127 128 @Test testIsVurAllowed_featureDisabled()129 public void testIsVurAllowed_featureDisabled() { 130 CarPropertyConfig config = mock(CarPropertyConfig.class); 131 when(config.getChangeMode()).thenReturn( 132 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS); 133 FeatureFlags featureFlags = mock(FeatureFlags.class); 134 when(featureFlags.variableUpdateRate()).thenReturn(false); 135 136 assertThat(InputSanitizationUtils.isVurAllowed(featureFlags, config)).isFalse(); 137 } 138 139 @Test testIsVurAllowed_propertyNotContinuous()140 public void testIsVurAllowed_propertyNotContinuous() { 141 CarPropertyConfig config = mock(CarPropertyConfig.class); 142 when(config.getChangeMode()).thenReturn( 143 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE); 144 FeatureFlags featureFlags = mock(FeatureFlags.class); 145 when(featureFlags.variableUpdateRate()).thenReturn(true); 146 147 assertThat(InputSanitizationUtils.isVurAllowed(featureFlags, config)).isFalse(); 148 } 149 150 @Test testSanitizeEnableVariableUpdateRate()151 public void testSanitizeEnableVariableUpdateRate() { 152 CarSubscription inputOption = newCarSubscription(PROPERTY_ID, new int[]{1, 2, 3}, 153 DEFAULT_UPDATE_RATE_HZ, true); 154 155 FeatureFlags featureFlags = mock(FeatureFlags.class); 156 when(featureFlags.variableUpdateRate()).thenReturn(true); 157 CarPropertyConfig config = mock(CarPropertyConfig.class); 158 when(config.getChangeMode()).thenReturn( 159 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS); 160 AreaIdConfig areaIdConfigEnabled = mock(AreaIdConfig.class); 161 when(areaIdConfigEnabled.isVariableUpdateRateSupported()).thenReturn(true); 162 AreaIdConfig areaIdConfigDisabled = mock(AreaIdConfig.class); 163 when(areaIdConfigDisabled.isVariableUpdateRateSupported()).thenReturn(false); 164 when(config.getAreaIdConfig(1)).thenReturn(areaIdConfigEnabled); 165 when(config.getAreaIdConfig(2)).thenThrow(new IllegalArgumentException()); 166 when(config.getAreaIdConfig(3)).thenReturn(areaIdConfigDisabled); 167 168 List<CarSubscription> sanitizedOptions = 169 InputSanitizationUtils.sanitizeEnableVariableUpdateRate(featureFlags, config, 170 inputOption); 171 172 assertThat(sanitizedOptions).containsExactly( 173 newCarSubscription(PROPERTY_ID, new int[]{1}, DEFAULT_UPDATE_RATE_HZ, true), 174 newCarSubscription(PROPERTY_ID, new int[]{2, 3}, DEFAULT_UPDATE_RATE_HZ, false)); 175 } 176 177 @Test testSanitizeResolution()178 public void testSanitizeResolution() { 179 FeatureFlags featureFlags = mock(FeatureFlags.class); 180 CarPropertyConfig config = mock(CarPropertyConfig.class); 181 when(config.getChangeMode()).thenReturn( 182 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE); 183 when(featureFlags.subscriptionWithResolution()).thenReturn(false); 184 185 assertThat(InputSanitizationUtils.sanitizeResolution(featureFlags, 186 config, 123.456f)).isEqualTo(0.0f); 187 188 when(featureFlags.subscriptionWithResolution()).thenReturn(true); 189 assertThat(InputSanitizationUtils.sanitizeResolution(featureFlags, 190 config, 123.456f)).isEqualTo(0.0f); 191 192 when(config.getChangeMode()).thenReturn( 193 CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS); 194 assertThat(InputSanitizationUtils.sanitizeResolution(featureFlags, 195 config, 0.0f)).isEqualTo(0.0f); 196 assertThat(InputSanitizationUtils.sanitizeResolution(featureFlags, 197 config, 0.1f)).isEqualTo(0.1f); 198 assertThat(InputSanitizationUtils.sanitizeResolution(featureFlags, 199 config, 1.0f)).isEqualTo(1.0f); 200 assertThrows(IllegalArgumentException.class, 201 () -> InputSanitizationUtils.sanitizeResolution(featureFlags, 202 config, 2.0f)); 203 } 204 newCarSubscription(int propertyId, int[] areaIds, float updateRateHz, boolean enableVur)205 private static CarSubscription newCarSubscription(int propertyId, int[] areaIds, 206 float updateRateHz, boolean enableVur) { 207 CarSubscription option = new CarSubscription(); 208 option.propertyId = propertyId; 209 option.areaIds = areaIds; 210 option.updateRateHz = updateRateHz; 211 option.enableVariableUpdateRate = enableVur; 212 return option; 213 } 214 } 215