• 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         when(mResources.getBoolean(R.bool.ccc_ranging_stopped_params_send_enabled))
149                 .thenReturn(false);
150         when(mResources.getBoolean(R.bool.ccc_absolute_uwb_initiation_time_enabled))
151                 .thenReturn(false);
152         when(mResources.getBoolean(R.bool.location_use_for_country_code_enabled))
153                 .thenReturn(true);
154         when(mResources.getBoolean(R.bool.uwb_disabled_until_first_toggle))
155                 .thenReturn(false);
156         when(mResources.getBoolean(R.bool.persistent_cache_use_for_country_code_enabled))
157                 .thenReturn(false);
158         when(mResources.getBoolean(R.bool.hw_idle_turn_off_enabled))
159                 .thenReturn(false);
160         when(mResources.getBoolean(R.bool.fused_country_code_provider_enabled))
161                 .thenReturn(false);
162         when(mResources.getBoolean(R.bool.is_antenna_mode_config_supported))
163                 .thenReturn(false);
164 
165         when(mContext.getResources()).thenReturn(mResources);
166 
167         mDeviceConfigFacade = new DeviceConfigFacade(new Handler(mLooper.getLooper()),
168                 mContext);
169         verify(() -> DeviceConfig.addOnPropertiesChangedListener(anyString(), any(),
170                 mOnPropertiesChangedListenerCaptor.capture()));
171     }
172 
173     /**
174      * Called after each test
175      */
176     @After
cleanup()177     public void cleanup() {
178         validateMockitoUsage();
179         mSession.finishMocking();
180     }
181 
182     /**
183      * Verifies that default values are set correctly
184      */
185     @Test
testDefaultValue()186     public void testDefaultValue() throws Exception {
187         assertEquals(DeviceConfigFacade.DEFAULT_RANGING_RESULT_LOG_INTERVAL_MS,
188                 mDeviceConfigFacade.getRangingResultLogIntervalMs());
189         assertEquals(true, mDeviceConfigFacade.isDeviceErrorBugreportEnabled());
190         assertEquals(true, mDeviceConfigFacade.isSessionInitErrorBugreportEnabled());
191         assertEquals(DeviceConfigFacade.DEFAULT_BUG_REPORT_MIN_INTERVAL_MS,
192                 mDeviceConfigFacade.getBugReportMinIntervalMs());
193 
194         assertEquals(true, mDeviceConfigFacade.isEnableFilters());
195         assertEquals(true, mDeviceConfigFacade.isEnablePrimerEstElevation());
196         assertEquals(true, mDeviceConfigFacade.isEnablePrimerAoA());
197         assertEquals(true, mDeviceConfigFacade.isEnableBackAzimuth());
198         assertEquals(true, mDeviceConfigFacade.isEnableBackAzimuthMasking());
199 
200         assertEquals(1, mDeviceConfigFacade.getFilterDistanceInliersPercent());
201         assertEquals(2, mDeviceConfigFacade.getFilterDistanceWindow());
202         assertEquals(3, mDeviceConfigFacade.getFilterAngleInliersPercent());
203         assertEquals(4, mDeviceConfigFacade.getFilterAngleWindow());
204         assertEquals(5, mDeviceConfigFacade.getPrimerFovDegree());
205         assertEquals(PoseSourceType.ROTATION_VECTOR, mDeviceConfigFacade.getPoseSourceType());
206         assertEquals(6, mDeviceConfigFacade.getPredictionTimeoutSeconds());
207         assertEquals(7, mDeviceConfigFacade.getBackAzimuthWindow());
208         assertEquals(
209                 Math.toRadians(8),
210                 mDeviceConfigFacade.getFrontAzimuthRadiansPerSecond(),
211                 0.001);
212         assertEquals(
213                 Math.toRadians(9),
214                 mDeviceConfigFacade.getBackAzimuthRadiansPerSecond(),
215                 0.001);
216         assertEquals(
217                 Math.toRadians(10),
218                 mDeviceConfigFacade.getMirrorScoreStdRadians(),
219                 0.001);
220         assertEquals(
221                 11 / 100F,
222                 mDeviceConfigFacade.getBackNoiseInfluenceCoeff(),
223                 0.001);
224 
225         // true because FOV is 5: within limits.
226         assertEquals(true, mDeviceConfigFacade.isEnablePrimerFov());
227 
228         // Check the default values for the Advertising profile and Rx packet parameters.
229         assertEquals(5, mDeviceConfigFacade.getAdvertiseAoaCriteriaAngle());
230         assertEquals(2000, mDeviceConfigFacade.getAdvertiseTimeThresholdMillis());
231         assertEquals(12, mDeviceConfigFacade.getAdvertiseArraySizeToCheck());
232         assertEquals(3, mDeviceConfigFacade.getAdvertiseArrayStartIndexToCalVariance());
233         assertEquals(7, mDeviceConfigFacade.getAdvertiseArrayEndIndexToCalVariance());
234         assertEquals(12, mDeviceConfigFacade.getAdvertiseTrustedVarianceValue());
235         assertEquals(10, mDeviceConfigFacade.getRxDataMaxPacketsToStore());
236         assertEquals(false, mDeviceConfigFacade.isBackgroundRangingEnabled());
237         assertEquals(true, mDeviceConfigFacade.isRangingErrorStreakTimerEnabled());
238         assertEquals(false, mDeviceConfigFacade.isCccRangingStoppedParamsSendEnabled());
239         assertEquals(false, mDeviceConfigFacade.isCccAbsoluteUwbInitiationTimeEnabled());
240         assertEquals(true, mDeviceConfigFacade.isLocationUseForCountryCodeEnabled());
241         assertEquals(false, mDeviceConfigFacade.isUwbDisabledUntilFirstToggle());
242         assertEquals(false, mDeviceConfigFacade.isPersistentCacheUseForCountryCodeEnabled());
243         assertEquals(false, mDeviceConfigFacade.isHwIdleTurnOffEnabled());
244         assertEquals(false, mDeviceConfigFacade.isFusedCountryCodeProviderEnabled());
245         assertEquals(false, mDeviceConfigFacade.isAntennaModeConfigSupported());
246     }
247 
248     /**
249      * Verifies that all fields are updated properly.
250      */
251     @Test
testFieldUpdates()252     public void testFieldUpdates() throws Exception {
253         // These are interwoven (change then check, repeated) to make sure that copypasta
254         //  errors didn't cause two values to get flipped.
255 
256         // Simulate updating the fields, make sure the corresponding call is updated.
257         when(DeviceConfig.getInt(anyString(), eq("ranging_result_log_interval_ms"),
258                 anyInt())).thenReturn(4000);
259         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
260         assertEquals(4000, mDeviceConfigFacade.getRangingResultLogIntervalMs());
261 
262         when(DeviceConfig.getBoolean(anyString(), eq("device_error_bugreport_enabled"),
263                 anyBoolean())).thenReturn(true);
264         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
265         assertEquals(true, mDeviceConfigFacade.isDeviceErrorBugreportEnabled());
266 
267         when(DeviceConfig.getBoolean(anyString(), eq("session_init_error_bugreport_enabled"),
268                 anyBoolean())).thenReturn(true);
269         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
270         assertEquals(true, mDeviceConfigFacade.isSessionInitErrorBugreportEnabled());
271 
272         when(DeviceConfig.getInt(anyString(), eq("bug_report_min_interval_ms"),
273                 anyInt())).thenReturn(10 * 3600_000);
274         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
275         assertEquals(10 * 3600_000, mDeviceConfigFacade.getBugReportMinIntervalMs());
276 
277         when(DeviceConfig.getBoolean(anyString(), eq("enable_filters"),
278                 anyBoolean())).thenReturn(false);
279         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
280         assertEquals(false, mDeviceConfigFacade.isEnableFilters());
281 
282         when(DeviceConfig.getBoolean(anyString(), eq("enable_primer_est_elevation"),
283                 anyBoolean())).thenReturn(false);
284         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
285         assertEquals(false, mDeviceConfigFacade.isEnablePrimerEstElevation());
286 
287         when(DeviceConfig.getBoolean(anyString(), eq("enable_primer_aoa"),
288                 anyBoolean())).thenReturn(false);
289         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
290         assertEquals(false, mDeviceConfigFacade.isEnablePrimerAoA());
291 
292         when(DeviceConfig.getBoolean(anyString(), eq("enable_azimuth_mirroring"),
293                 anyBoolean())).thenReturn(false);
294         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
295         assertEquals(false, mDeviceConfigFacade.isEnableBackAzimuth());
296 
297         when(DeviceConfig.getBoolean(anyString(), eq("predict_rear_azimuths"),
298                 anyBoolean())).thenReturn(false);
299         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
300         assertEquals(false, mDeviceConfigFacade.isEnableBackAzimuthMasking());
301 
302         when(DeviceConfig.getInt(anyString(), eq("filter_distance_inliers_percent"),
303                 anyInt())).thenReturn(6);
304         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
305         assertEquals(6, mDeviceConfigFacade.getFilterDistanceInliersPercent());
306 
307         when(DeviceConfig.getInt(anyString(), eq("filter_distance_window"),
308                 anyInt())).thenReturn(7);
309         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
310         assertEquals(7, mDeviceConfigFacade.getFilterDistanceWindow());
311 
312         when(DeviceConfig.getInt(anyString(), eq("filter_angle_inliers_percent"),
313                 anyInt())).thenReturn(8);
314         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
315         assertEquals(8, mDeviceConfigFacade.getFilterAngleInliersPercent());
316 
317         when(DeviceConfig.getInt(anyString(), eq("filter_angle_window"),
318                 anyInt())).thenReturn(9);
319         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
320         assertEquals(9, mDeviceConfigFacade.getFilterAngleWindow());
321 
322         when(DeviceConfig.getInt(anyString(), eq("primer_fov_degrees"),
323                 anyInt())).thenReturn(0);
324         when(DeviceConfig.getString(anyString(), eq("pose_source_type"),
325                 anyString())).thenReturn("NONE");
326         when(DeviceConfig.getInt(anyString(), eq("prediction_timeout_seconds"),
327                 anyInt())).thenReturn(5);
328 
329         when(DeviceConfig.getInt(anyString(), eq("advertise_aoa_criteria_angle"), anyInt()))
330                 .thenReturn(20);
331         when(DeviceConfig.getInt(anyString(), eq("advertise_time_threshold_millis"), anyInt()))
332                 .thenReturn(3000);
333         when(DeviceConfig.getInt(anyString(), eq("advertise_array_size_to_check"), anyInt()))
334                 .thenReturn(15);
335         when(DeviceConfig.getInt(anyString(), eq("advertise_array_start_index_to_cal_variance"),
336                 anyInt())).thenReturn(3);
337         when(DeviceConfig.getInt(anyString(), eq("advertise_array_end_index_to_cal_variance"),
338                 anyInt())).thenReturn(7);
339         when(DeviceConfig.getInt(anyString(), eq("advertise_trusted_variance_value"), anyInt()))
340                 .thenReturn(12);
341         when(DeviceConfig.getInt(anyString(), eq("rx_data_max_packets_to_store"),
342                 anyInt())).thenReturn(20);
343         when(DeviceConfig.getBoolean(anyString(), eq("background_ranging_enabled"),
344                 anyBoolean())).thenReturn(true);
345         when(DeviceConfig.getBoolean(anyString(), eq("ranging_error_streak_timer_enabled"),
346                 anyBoolean())).thenReturn(false);
347         when(DeviceConfig.getBoolean(anyString(), eq("ccc_ranging_stopped_params_send_enabled"),
348                 anyBoolean())).thenReturn(true);
349         when(DeviceConfig.getBoolean(anyString(), eq("ccc_absolute_uwb_initiation_time_enabled"),
350                 anyBoolean())).thenReturn(true);
351         when(DeviceConfig.getBoolean(anyString(), eq("location_use_for_country_code_enabled"),
352                 anyBoolean())).thenReturn(false);
353         when(DeviceConfig.getBoolean(anyString(), eq("uwb_disabled_until_first_toggle"),
354                 anyBoolean())).thenReturn(true);
355         when(DeviceConfig.getBoolean(anyString(),
356                 eq("persistent_cache_use_for_country_code_enabled"),
357                 anyBoolean())).thenReturn(true);
358         when(DeviceConfig.getBoolean(anyString(), eq("hw_idle_turn_off_enabled"),
359                 anyBoolean())).thenReturn(true);
360         when(DeviceConfig.getBoolean(anyString(), eq("fused_country_code_provider_enabled"),
361                 anyBoolean())).thenReturn(true);
362         when(DeviceConfig.getBoolean(anyString(), eq("is_antenna_mode_config_supported"),
363                 anyBoolean())).thenReturn(true);
364 
365         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
366         assertEquals(0, mDeviceConfigFacade.getPrimerFovDegree());
367         // false because FOV is 0.
368         assertEquals(false, mDeviceConfigFacade.isEnablePrimerFov());
369 
370         assertEquals(20, mDeviceConfigFacade.getAdvertiseAoaCriteriaAngle());
371         assertEquals(3000, mDeviceConfigFacade.getAdvertiseTimeThresholdMillis());
372         assertEquals(15, mDeviceConfigFacade.getAdvertiseArraySizeToCheck());
373         assertEquals(3, mDeviceConfigFacade.getAdvertiseArrayStartIndexToCalVariance());
374         assertEquals(7 , mDeviceConfigFacade.getAdvertiseArrayEndIndexToCalVariance());
375         assertEquals(12, mDeviceConfigFacade.getAdvertiseTrustedVarianceValue());
376         assertEquals(20, mDeviceConfigFacade.getRxDataMaxPacketsToStore());
377         assertEquals(true, mDeviceConfigFacade.isBackgroundRangingEnabled());
378         assertEquals(false, mDeviceConfigFacade.isRangingErrorStreakTimerEnabled());
379         assertEquals(true, mDeviceConfigFacade.isCccRangingStoppedParamsSendEnabled());
380         assertEquals(true, mDeviceConfigFacade.isCccAbsoluteUwbInitiationTimeEnabled());
381         assertEquals(false, mDeviceConfigFacade.isLocationUseForCountryCodeEnabled());
382         assertEquals(true, mDeviceConfigFacade.isUwbDisabledUntilFirstToggle());
383         assertEquals(true, mDeviceConfigFacade.isPersistentCacheUseForCountryCodeEnabled());
384         assertEquals(true, mDeviceConfigFacade.isHwIdleTurnOffEnabled());
385         assertEquals(true, mDeviceConfigFacade.isFusedCountryCodeProviderEnabled());
386         assertEquals(true, mDeviceConfigFacade.isAntennaModeConfigSupported());
387         when(DeviceConfig.getString(anyString(), eq("pose_source_type"),
388                 anyString())).thenReturn("NONE");
389         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
390         assertEquals(PoseSourceType.NONE, mDeviceConfigFacade.getPoseSourceType());
391 
392         when(DeviceConfig.getInt(anyString(), eq("prediction_timeout_seconds"),
393                 anyInt())).thenReturn(5);
394         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
395         assertEquals(5, mDeviceConfigFacade.getPredictionTimeoutSeconds());
396 
397         when(DeviceConfig.getInt(anyString(), eq("mirror_detection_window"),
398                 anyInt())).thenReturn(11);
399         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
400         assertEquals(11, mDeviceConfigFacade.getBackAzimuthWindow());
401 
402         when(DeviceConfig.getInt(anyString(), eq("front_mirror_dps"),
403                 anyInt())).thenReturn(12);
404         when(DeviceConfig.getInt(anyString(), eq("back_mirror_dps"),
405                 anyInt())).thenReturn(13);
406         when(DeviceConfig.getInt(anyString(), eq("mirror_score_std_degrees"),
407                 anyInt())).thenReturn(14);
408         when(DeviceConfig.getInt(anyString(), eq("back_noise_influence_percent"),
409                 anyInt())).thenReturn(15);
410 
411         mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
412         assertEquals(
413                 Math.toRadians(12),
414                 mDeviceConfigFacade.getFrontAzimuthRadiansPerSecond(),
415                 0.001);
416         assertEquals(
417                 Math.toRadians(13),
418                 mDeviceConfigFacade.getBackAzimuthRadiansPerSecond(),
419                 0.001);
420         assertEquals(
421                 Math.toRadians(14),
422                 mDeviceConfigFacade.getMirrorScoreStdRadians(),
423                 0.001);
424         assertEquals(
425                 15 / 100F,
426                 mDeviceConfigFacade.getBackNoiseInfluenceCoeff(),
427                 0.001);
428     }
429 }
430