• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.extendedapitest;
18 
19 import static android.car.Car.CAR_PROPERTY_SIMULATION_SERVICE;
20 import static android.car.Car.PROPERTY_SERVICE;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 import static com.google.common.truth.Truth.assertWithMessage;
24 
25 import static org.junit.Assert.assertThrows;
26 import static org.junit.Assume.assumeTrue;
27 
28 import android.annotation.Nullable;
29 import android.car.Car;
30 import android.car.builtin.os.BuildHelper;
31 import android.car.extendedapitest.testbase.CarApiTestBase;
32 import android.car.feature.Flags;
33 import android.car.hardware.CarPropertyConfig;
34 import android.car.hardware.CarPropertyValue;
35 import android.car.hardware.property.CarPropertyManager;
36 import android.car.hardware.property.CarPropertySimulationManager;
37 import android.car.test.PermissionsCheckerRule;
38 import android.car.test.PermissionsCheckerRule.EnsureHasPermission;
39 import android.platform.test.annotations.RequiresFlagsEnabled;
40 
41 import androidx.annotation.NonNull;
42 
43 import com.android.compatibility.common.util.ApiTest;
44 
45 import org.junit.Before;
46 import org.junit.Rule;
47 import org.junit.Test;
48 
49 import java.util.List;
50 import java.util.concurrent.CountDownLatch;
51 import java.util.concurrent.TimeUnit;
52 
53 public class CarPropertySimulationManagerTest extends CarApiTestBase {
54 
55     private static final long TIMEOUT_MS = 5000;
56 
57     @Nullable
58     private CarPropertySimulationManager mCarPropertySimulationManager;
59     private CarPropertyManager mCarPropertyManager;
60 
61     @Rule
62     public final PermissionsCheckerRule mPermissionsCheckerRule = new PermissionsCheckerRule();
63 
64     @Before
setUp()65     public void setUp() throws Exception {
66         mCarPropertySimulationManager =
67                 (CarPropertySimulationManager)
68                         getCar().getCarManager(CAR_PROPERTY_SIMULATION_SERVICE);
69         mCarPropertyManager = (CarPropertyManager) getCar().getCarManager(PROPERTY_SERVICE);
70     }
71 
72     @Test
73     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
74     @ApiTest(
75             apis = {
76                     "android.car.CarProjectionManager#enableInjectionMode",
77                     "android.car.CarProjectionManager#isVehiclePropertyInjectionModeEnabled",
78                     "android.car.CarProjectionManager#disableInjectionMode"
79             })
80     @EnsureHasPermission(Car.PERMISSION_INJECT_VEHICLE_PROPERTIES)
testEnableInjectionMode()81     public void testEnableInjectionMode() {
82         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
83 
84         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isFalse();
85         long injectionModeStartTimeNanos =
86                 mCarPropertySimulationManager.enableInjectionMode(List.of());
87 
88         assertThat(injectionModeStartTimeNanos).isGreaterThan(0L);
89         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isTrue();
90         mCarPropertySimulationManager.disableInjectionMode();
91 
92         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isFalse();
93     }
94 
95     @Test
96     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
97     @ApiTest(
98             apis = {
99                     "android.car.CarProjectionManager#startRecordingVehicleProperties",
100                     "android.car.CarProjectionManager#isRecordingVehicleProperties",
101                     "android.car.CarProjectionManager#stopRecordingVehicleProperties"
102             })
103     @EnsureHasPermission(Car.PERMISSION_RECORD_VEHICLE_PROPERTIES)
testRecordingVehicleProperties()104     public void testRecordingVehicleProperties() throws Exception {
105         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
106 
107         CountDownLatch onRecordingFinishedLatch = new CountDownLatch(1);
108         CarRecordingListener listener = new CarRecordingListener(/* carPropertyEventsLatch= */ null,
109                 onRecordingFinishedLatch);
110         List<CarPropertyConfig> configList = mCarPropertyManager.getPropertyList();
111 
112         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
113         List<CarPropertyConfig> carPropertyConfigsRecorded =
114                 mCarPropertySimulationManager.startRecordingVehicleProperties(
115                         /* callbackExecutor= */ null, listener);
116 
117         assertThat(carPropertyConfigsRecorded).isNotNull();
118         assertThat(carPropertyConfigsRecorded.size()).isAtLeast(configList.size());
119         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isTrue();
120         mCarPropertySimulationManager.stopRecordingVehicleProperties();
121         assertWithMessage("CarPropertySimulationManager stop recording")
122                 .that(onRecordingFinishedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
123         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
124     }
125 
126     @Test
127     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
128     @ApiTest(
129             apis = {
130                     "android.car.CarProjectionManager#startRecordingVehicleProperties",
131                     "android.car.CarProjectionManager#isRecordingVehicleProperties",
132                     "android.car.CarProjectionManager#stopRecordingVehicleProperties"
133             })
134     @EnsureHasPermission(Car.PERMISSION_RECORD_VEHICLE_PROPERTIES)
testRecordingVehiclePropertiesTwice()135     public void testRecordingVehiclePropertiesTwice() throws Exception {
136         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
137 
138         CountDownLatch onRecordingFinishedLatch = new CountDownLatch(1);
139         CarRecordingListener listener = new CarRecordingListener(/* carPropertyEventsLatch= */ null,
140                 onRecordingFinishedLatch);
141 
142         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
143         mCarPropertySimulationManager.startRecordingVehicleProperties(
144                 /* callbackExecutor= */ null, listener);
145         IllegalStateException thrown =
146                 assertThrows(
147                         IllegalStateException.class,
148                         () ->
149                                 mCarPropertySimulationManager.startRecordingVehicleProperties(
150                                         /* callbackExecutor= */ null, listener));
151 
152         assertThat(thrown).hasMessageThat().contains("Recording already in progress");
153         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isTrue();
154         mCarPropertySimulationManager.stopRecordingVehicleProperties();
155         assertWithMessage("CarPropertySimulationManager stop recording")
156                 .that(onRecordingFinishedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
157         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
158     }
159 
160     @Test
161     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
162     @ApiTest(apis = {"android.car.CarProjectionManager#startRecordingVehicleProperties"})
163     @EnsureHasPermission(Car.PERMISSION_RECORD_VEHICLE_PROPERTIES)
testRecordingVehiclePropertiesNullListener()164     public void testRecordingVehiclePropertiesNullListener() {
165         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
166 
167         assertThrows(
168                 NullPointerException.class,
169                 () ->
170                         mCarPropertySimulationManager.startRecordingVehicleProperties(
171                                 /* callbackExecutor= */ null, /* listener= */ null));
172     }
173 
174     @Test
175     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
176     @ApiTest(
177             apis = {
178                     "android.car.CarProjectionManager#enableInjectionMode",
179                     "android.car.CarProjectionManager#isVehiclePropertyInjectionModeEnabled",
180                     "android.car.CarProjectionManager#disableInjectionMode"
181             })
182     @EnsureHasPermission(Car.PERMISSION_INJECT_VEHICLE_PROPERTIES)
testEnableInjectionModeTwice()183     public void testEnableInjectionModeTwice() {
184         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
185 
186         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isFalse();
187         long injectionStartTime = mCarPropertySimulationManager.enableInjectionMode(List.of());
188         assertThat(injectionStartTime).isAtLeast(0L);
189         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isTrue();
190 
191         long secondInjectionStartTime =
192                 mCarPropertySimulationManager.enableInjectionMode(List.of());
193 
194         assertThat(secondInjectionStartTime).isEqualTo(-1L);
195         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isTrue();
196         mCarPropertySimulationManager.disableInjectionMode();
197         assertThat(mCarPropertySimulationManager.isVehiclePropertyInjectionModeEnabled()).isFalse();
198     }
199 
200     @Test
201     @RequiresFlagsEnabled(Flags.FLAG_CAR_PROPERTY_SIMULATION)
202     @ApiTest(
203             apis = {
204                     "android.car.CarProjectionManager#isRecordingVehicleProperties",
205                     "android.car.CarProjectionManager#stopRecordingVehicleProperties"
206             })
207     @EnsureHasPermission(Car.PERMISSION_RECORD_VEHICLE_PROPERTIES)
testStopRecordingVehiclePropertiesWhenAlreadyDisabled()208     public void testStopRecordingVehiclePropertiesWhenAlreadyDisabled() {
209         assumeTrue(BuildHelper.isEngBuild() || BuildHelper.isUserDebugBuild());
210 
211         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
212         mCarPropertySimulationManager.stopRecordingVehicleProperties();
213         assertThat(mCarPropertySimulationManager.isRecordingVehicleProperties()).isFalse();
214     }
215 
216     private static final class CarRecordingListener
217             implements CarPropertySimulationManager.CarRecorderListener {
218 
219         private final CountDownLatch mCarPropertyEventsLatch;
220         private final CountDownLatch mCarPropertyFinishedLatch;
221 
CarRecordingListener( CountDownLatch carPropertyEventsLatch, CountDownLatch onRecordingFinishedLatch)222         private CarRecordingListener(
223                 CountDownLatch carPropertyEventsLatch, CountDownLatch onRecordingFinishedLatch) {
224             mCarPropertyEventsLatch =
225                     carPropertyEventsLatch == null ? new CountDownLatch(0) : carPropertyEventsLatch;
226             mCarPropertyFinishedLatch =
227                     onRecordingFinishedLatch == null
228                             ? new CountDownLatch(0)
229                             : onRecordingFinishedLatch;
230         }
231 
232         @Override
onCarPropertyEvents(@onNull List<CarPropertyValue<?>> carPropertyValues)233         public void onCarPropertyEvents(@NonNull List<CarPropertyValue<?>> carPropertyValues) {
234             mCarPropertyEventsLatch.countDown();
235         }
236 
237         @Override
onRecordingFinished()238         public void onRecordingFinished() {
239             mCarPropertyFinishedLatch.countDown();
240         }
241     }
242 
243 }
244