• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.server.uwb;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyBoolean;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.ArgumentMatchers.anyLong;
26 import static org.mockito.ArgumentMatchers.anyString;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.validateMockitoUsage;
29 import static org.mockito.Mockito.when;
30 import static org.mockito.Mockito.withSettings;
31 
32 import android.app.test.MockAnswerUtil;
33 import android.content.Context;
34 import android.content.res.Resources;
35 import android.os.Handler;
36 import android.os.test.TestLooper;
37 import android.provider.DeviceConfig;
38 
39 import com.android.dx.mockito.inline.extended.ExtendedMockito;
40 import com.android.server.uwb.DeviceConfigFacade.PoseSourceType;
41 import com.android.uwb.resources.R;
42 
43 import org.junit.After;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.mockito.ArgumentCaptor;
47 import org.mockito.Mock;
48 import org.mockito.MockitoAnnotations;
49 import org.mockito.MockitoSession;
50 
51 public class DeviceConfigFacadeTest {
52     @Mock private Resources mResources;
53     @Mock private Context mContext;
54 
55     final ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener>
56             mOnPropertiesChangedListenerCaptor =
57             ArgumentCaptor.forClass(DeviceConfig.OnPropertiesChangedListener.class);
58 
59     private DeviceConfigFacade mDeviceConfigFacade;
60     private TestLooper mLooper = new TestLooper();
61     private MockitoSession mSession;
62 
63     /**
64      * Setup the mocks and an instance of DeviceConfig before each test.
65      */
66     @Before
setUp()67     public void setUp() throws Exception {
68         MockitoAnnotations.initMocks(this);
69         // static mocking
70         mSession = ExtendedMockito.mockitoSession()
71                 .mockStatic(DeviceConfig.class, withSettings().lenient())
72                 .startMocking();
73         // Have DeviceConfig return the default value passed in.
74         when(DeviceConfig.getBoolean(anyString(), anyString(), anyBoolean()))
75                 .then(new MockAnswerUtil.AnswerWithArguments() {
76                     public boolean answer(String namespace, String field, boolean def) {
77                         return def;
78                     }
79                 });
80         when(DeviceConfig.getInt(anyString(), anyString(), anyInt()))
81                 .then(new MockAnswerUtil.AnswerWithArguments() {
82                     public int answer(String namespace, String field, int def) {
83                         return def;
84                     }
85                 });
86         when(DeviceConfig.getLong(anyString(), anyString(), anyLong()))
87                 .then(new MockAnswerUtil.AnswerWithArguments() {
88                     public long answer(String namespace, String field, long def) {
89                         return def;
90                     }
91                 });
92         when(DeviceConfig.getString(anyString(), anyString(), anyString()))
93                 .then(new MockAnswerUtil.AnswerWithArguments() {
94                     public String answer(String namespace, String field, String def) {
95                         return def;
96                     }
97                 });
98 
99         when(mResources.getBoolean(R.bool.enable_filters)).thenReturn(true);
100         when(mResources.getBoolean(R.bool.enable_primer_est_elevation)).thenReturn(true);
101         when(mResources.getBoolean(R.bool.enable_primer_aoa)).thenReturn(true);
102         when(mResources.getInteger(R.integer.filter_distance_inliers_percent))
103                 .thenReturn(1);
104         when(mResources.getInteger(R.integer.filter_distance_window))
105                 .thenReturn(2);
106         when(mResources.getInteger(R.integer.filter_angle_inliers_percent))
107                 .thenReturn(3);
108         when(mResources.getInteger(R.integer.filter_angle_window))
109                 .thenReturn(4);
110         when(mResources.getInteger(R.integer.primer_fov_degrees))
111                 .thenReturn(5);
112         when(mResources.getString(R.string.pose_source_type))
113                 .thenReturn("ROTATION_VECTOR");
114         when(mResources.getInteger(R.integer.prediction_timeout_seconds))
115                 .thenReturn(6);
116         when(mResources.getBoolean(R.bool.enable_azimuth_mirroring)).thenReturn(true);
117         when(mResources.getBoolean(R.bool.predict_rear_azimuths)).thenReturn(true);
118         when(mResources.getInteger(R.integer.mirror_detection_window))
119                 .thenReturn(7);
120         when(mResources.getInteger(R.integer.front_mirror_dps))
121                 .thenReturn(8);
122         when(mResources.getInteger(R.integer.back_mirror_dps))
123                 .thenReturn(9);
124         when(mResources.getInteger(R.integer.mirror_score_std_degrees))
125                 .thenReturn(10);
126         when(mResources.getInteger(R.integer.back_noise_influence_percent))
127                 .thenReturn(11);
128 
129         // Setup the default values for the Advertising profile and Rx data packet parameters.
130         when(mResources.getInteger(R.integer.advertise_aoa_criteria_angle))
131                 .thenReturn(5);
132         when(mResources.getInteger(R.integer.advertise_time_threshold_millis))
133                 .thenReturn(2000);
134         when(mResources.getInteger(R.integer.advertise_array_size_to_check))
135                 .thenReturn(12);
136         when(mResources.getInteger(R.integer.advertise_array_start_index_to_cal_variance))
137                 .thenReturn(3);
138         when(mResources.getInteger(R.integer.advertise_array_end_index_to_cal_variance))
139                 .thenReturn(7);
140         when(mResources.getInteger(R.integer.advertise_trusted_variance_value))
141                 .thenReturn(12);
142         when(mResources.getInteger(R.integer.rx_data_max_packets_to_store))
143                 .thenReturn(10);
144         when(mResources.getBoolean(R.bool.background_ranging_enabled))
145                 .thenReturn(false);
146         when(mResources.getBoolean(R.bool.ranging_error_streak_timer_enabled))
147                 .thenReturn(true);
148 
149         when(mContext.getResources()).thenReturn(mResources);
150 
151         mDeviceConfigFacade = new DeviceConfigFacade(new Handler(mLooper.getLooper()),
152                 mContext);
153         verify(() -> DeviceConfig.addOnPropertiesChangedListener(anyString(), any(),
154                 mOnPropertiesChangedListenerCaptor.capture()));
155     }
156 
157     /**
158      * Called after each test
159      */
160     @After
cleanup()161     public void cleanup() {
162         validateMockitoUsage();
163         mSession.finishMocking();
164     }
165 
166     /**
167      * Verifies that default values are set correctly
168      */
169     @Test
testDefaultValue()170     public void testDefaultValue() throws Exception {
171         assertEquals(DeviceConfigFacade.DEFAULT_RANGING_RESULT_LOG_INTERVAL_MS,
172                 mDeviceConfigFacade.getRangingResultLogIntervalMs());
173         assertEquals(false, mDeviceConfigFacade.isDeviceErrorBugreportEnabled());
174         assertEquals(false, mDeviceConfigFacade.isSessionInitErrorBugreportEnabled());
175         assertEquals(DeviceConfigFacade.DEFAULT_BUG_REPORT_MIN_INTERVAL_MS,
176                 mDeviceConfigFacade.getBugReportMinIntervalMs());
177 
178         assertEquals(true, mDeviceConfigFacade.isEnableFilters());
179         assertEquals(true, mDeviceConfigFacade.isEnablePrimerEstElevation());
180         assertEquals(true, mDeviceConfigFacade.isEnablePrimerAoA());
181         assertEquals(true, mDeviceConfigFacade.isEnableBackAzimuth());
182         assertEquals(true, mDeviceConfigFacade.isEnableBackAzimuthMasking());
183 
184         assertEquals(1, mDeviceConfigFacade.getFilterDistanceInliersPercent());
185         assertEquals(2, mDeviceConfigFacade.getFilterDistanceWindow());
186         assertEquals(3, mDeviceConfigFacade.getFilterAngleInliersPercent());
187         assertEquals(4, mDeviceConfigFacade.getFilterAngleWindow());
188         assertEquals(5, mDeviceConfigFacade.getPrimerFovDegree());
189         assertEquals(PoseSourceType.ROTATION_VECTOR, mDeviceConfigFacade.getPoseSourceType());
190         assertEquals(6, mDeviceConfigFacade.getPredictionTimeoutSeconds());
191         assertEquals(7, mDeviceConfigFacade.getBackAzimuthWindow());
192         assertEquals(
193                 Math.toRadians(8),
194                 mDeviceConfigFacade.getFrontAzimuthRadiansPerSecond(),
195                 0.001);
196         assertEquals(
197                 Math.toRadians(9),
198                 mDeviceConfigFacade.getBackAzimuthRadiansPerSecond(),
199                 0.001);
200         assertEquals(
201                 Math.toRadians(10),
202                 mDeviceConfigFacade.getMirrorScoreStdRadians(),
203                 0.001);
204         assertEquals(
205                 11 / 100F,
206                 mDeviceConfigFacade.getBackNoiseInfluenceCoeff(),
207                 0.001);
208 
209         // true because FOV is 5: within limits.
210         assertEquals(true, mDeviceConfigFacade.isEnablePrimerFov());
211 
212         // Check the default values for the Advertising profile and Rx packet parameters.
213         assertEquals(5, mDeviceConfigFacade.getAdvertiseAoaCriteriaAngle());
214         assertEquals(2000, mDeviceConfigFacade.getAdvertiseTimeThresholdMillis());
215         assertEquals(12, mDeviceConfigFacade.getAdvertiseArraySizeToCheck());
216         assertEquals(3, mDeviceConfigFacade.getAdvertiseArrayStartIndexToCalVariance());
217         assertEquals(7, mDeviceConfigFacade.getAdvertiseArrayEndIndexToCalVariance());
218         assertEquals(12, mDeviceConfigFacade.getAdvertiseTrustedVarianceValue());
219         assertEquals(10, mDeviceConfigFacade.getRxDataMaxPacketsToStore());
220         assertEquals(false, mDeviceConfigFacade.isBackgroundRangingEnabled());
221         assertEquals(true, mDeviceConfigFacade.isRangingErrorStreakTimerEnabled());
222     }
223 
224     /**
225      * Verifies that all fields are updated properly.
226      */
227     @Test
testFieldUpdates()228     public void testFieldUpdates() throws Exception {
229         // These are interwoven (change then check, repeated) to make sure that copypasta
230         //  errors didn't cause two values to get flipped.
231 
232         // Simulate updating the fields, make sure the corresponding call is updated.
233         when(DeviceConfig.getInt(anyString(), eq("ranging_result_log_interval_ms"),
234                 anyInt())).thenReturn(4000);
235         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
236         assertEquals(4000, mDeviceConfigFacade.getRangingResultLogIntervalMs());
237 
238         when(DeviceConfig.getBoolean(anyString(), eq("device_error_bugreport_enabled"),
239                 anyBoolean())).thenReturn(true);
240         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
241         assertEquals(true, mDeviceConfigFacade.isDeviceErrorBugreportEnabled());
242 
243         when(DeviceConfig.getInt(anyString(), eq("bug_report_min_interval_ms"),
244                 anyInt())).thenReturn(10 * 3600_000);
245         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
246         assertEquals(10 * 3600_000, mDeviceConfigFacade.getBugReportMinIntervalMs());
247 
248         when(DeviceConfig.getBoolean(anyString(), eq("enable_filters"),
249                 anyBoolean())).thenReturn(false);
250         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
251         assertEquals(false, mDeviceConfigFacade.isEnableFilters());
252 
253         when(DeviceConfig.getBoolean(anyString(), eq("enable_primer_est_elevation"),
254                 anyBoolean())).thenReturn(false);
255         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
256         assertEquals(false, mDeviceConfigFacade.isEnablePrimerEstElevation());
257 
258         when(DeviceConfig.getBoolean(anyString(), eq("enable_primer_aoa"),
259                 anyBoolean())).thenReturn(false);
260         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
261         assertEquals(false, mDeviceConfigFacade.isEnablePrimerAoA());
262 
263         when(DeviceConfig.getBoolean(anyString(), eq("enable_azimuth_mirroring"),
264                 anyBoolean())).thenReturn(false);
265         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
266         assertEquals(false, mDeviceConfigFacade.isEnableBackAzimuth());
267 
268         when(DeviceConfig.getBoolean(anyString(), eq("predict_rear_azimuths"),
269                 anyBoolean())).thenReturn(false);
270         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
271         assertEquals(false, mDeviceConfigFacade.isEnableBackAzimuthMasking());
272 
273         when(DeviceConfig.getInt(anyString(), eq("filter_distance_inliers_percent"),
274                 anyInt())).thenReturn(6);
275         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
276         assertEquals(6, mDeviceConfigFacade.getFilterDistanceInliersPercent());
277 
278         when(DeviceConfig.getInt(anyString(), eq("filter_distance_window"),
279                 anyInt())).thenReturn(7);
280         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
281         assertEquals(7, mDeviceConfigFacade.getFilterDistanceWindow());
282 
283         when(DeviceConfig.getInt(anyString(), eq("filter_angle_inliers_percent"),
284                 anyInt())).thenReturn(8);
285         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
286         assertEquals(8, mDeviceConfigFacade.getFilterAngleInliersPercent());
287 
288         when(DeviceConfig.getInt(anyString(), eq("filter_angle_window"),
289                 anyInt())).thenReturn(9);
290         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
291         assertEquals(9, mDeviceConfigFacade.getFilterAngleWindow());
292 
293         when(DeviceConfig.getInt(anyString(), eq("primer_fov_degrees"),
294                 anyInt())).thenReturn(0);
295         when(DeviceConfig.getString(anyString(), eq("pose_source_type"),
296                 anyString())).thenReturn("NONE");
297         when(DeviceConfig.getInt(anyString(), eq("prediction_timeout_seconds"),
298                 anyInt())).thenReturn(5);
299 
300         when(DeviceConfig.getInt(anyString(), eq("advertise_aoa_criteria_angle"), anyInt()))
301                 .thenReturn(20);
302         when(DeviceConfig.getInt(anyString(), eq("advertise_time_threshold_millis"), anyInt()))
303                 .thenReturn(3000);
304         when(DeviceConfig.getInt(anyString(), eq("advertise_array_size_to_check"), anyInt()))
305                 .thenReturn(15);
306         when(DeviceConfig.getInt(anyString(), eq("advertise_array_start_index_to_cal_variance"),
307                 anyInt())).thenReturn(3);
308         when(DeviceConfig.getInt(anyString(), eq("advertise_array_end_index_to_cal_variance"),
309                 anyInt())).thenReturn(7);
310         when(DeviceConfig.getInt(anyString(), eq("advertise_trusted_variance_value"), anyInt()))
311                 .thenReturn(12);
312         when(DeviceConfig.getInt(anyString(), eq("rx_data_max_packets_to_store"),
313                 anyInt())).thenReturn(20);
314         when(DeviceConfig.getBoolean(anyString(), eq("background_ranging_enabled"),
315                 anyBoolean())).thenReturn(true);
316         when(DeviceConfig.getBoolean(anyString(), eq("ranging_error_streak_timer_enabled"),
317                 anyBoolean())).thenReturn(false);
318 
319         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
320         assertEquals(0, mDeviceConfigFacade.getPrimerFovDegree());
321         // false because FOV is 0.
322         assertEquals(false, mDeviceConfigFacade.isEnablePrimerFov());
323 
324         assertEquals(20, mDeviceConfigFacade.getAdvertiseAoaCriteriaAngle());
325         assertEquals(3000, mDeviceConfigFacade.getAdvertiseTimeThresholdMillis());
326         assertEquals(15, mDeviceConfigFacade.getAdvertiseArraySizeToCheck());
327         assertEquals(3, mDeviceConfigFacade.getAdvertiseArrayStartIndexToCalVariance());
328         assertEquals(7 , mDeviceConfigFacade.getAdvertiseArrayEndIndexToCalVariance());
329         assertEquals(12, mDeviceConfigFacade.getAdvertiseTrustedVarianceValue());
330         assertEquals(20, mDeviceConfigFacade.getRxDataMaxPacketsToStore());
331         assertEquals(true, mDeviceConfigFacade.isBackgroundRangingEnabled());
332         assertEquals(false, mDeviceConfigFacade.isRangingErrorStreakTimerEnabled());
333         when(DeviceConfig.getString(anyString(), eq("pose_source_type"),
334                 anyString())).thenReturn("NONE");
335         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
336         assertEquals(PoseSourceType.NONE, mDeviceConfigFacade.getPoseSourceType());
337 
338         when(DeviceConfig.getInt(anyString(), eq("prediction_timeout_seconds"),
339                 anyInt())).thenReturn(5);
340         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
341         assertEquals(5, mDeviceConfigFacade.getPredictionTimeoutSeconds());
342 
343         when(DeviceConfig.getInt(anyString(), eq("mirror_detection_window"),
344                 anyInt())).thenReturn(11);
345         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
346         assertEquals(11, mDeviceConfigFacade.getBackAzimuthWindow());
347 
348         when(DeviceConfig.getInt(anyString(), eq("front_mirror_dps"),
349                 anyInt())).thenReturn(12);
350         when(DeviceConfig.getInt(anyString(), eq("back_mirror_dps"),
351                 anyInt())).thenReturn(13);
352         when(DeviceConfig.getInt(anyString(), eq("mirror_score_std_degrees"),
353                 anyInt())).thenReturn(14);
354         when(DeviceConfig.getInt(anyString(), eq("back_noise_influence_percent"),
355                 anyInt())).thenReturn(15);
356 
357         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
358         assertEquals(
359                 Math.toRadians(12),
360                 mDeviceConfigFacade.getFrontAzimuthRadiansPerSecond(),
361                 0.001);
362         assertEquals(
363                 Math.toRadians(13),
364                 mDeviceConfigFacade.getBackAzimuthRadiansPerSecond(),
365                 0.001);
366         assertEquals(
367                 Math.toRadians(14),
368                 mDeviceConfigFacade.getMirrorScoreStdRadians(),
369                 0.001);
370         assertEquals(
371                 15 / 100F,
372                 mDeviceConfigFacade.getBackNoiseInfluenceCoeff(),
373                 0.001);
374     }
375 }
376