• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.hardware.automotive.vehicle.TestVendorProperty.VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.junit.Assert.assertThrows;
24 import static org.junit.Assume.assumeTrue;
25 
26 import android.car.Car;
27 import android.car.extendedapitest.testbase.CarApiTestBase;
28 import android.car.hardware.CarPropertyConfig;
29 import android.car.hardware.property.CarInternalErrorException;
30 import android.car.hardware.property.CarPropertyManager;
31 import android.car.test.CarTestManager;
32 import android.hardware.automotive.vehicle.VehicleArea;
33 import android.hardware.automotive.vehicle.VehiclePropertyGroup;
34 import android.hardware.automotive.vehicle.VehiclePropertyType;
35 import android.os.Binder;
36 import android.os.Handler;
37 import android.os.HandlerExecutor;
38 import android.os.HandlerThread;
39 import android.util.ArraySet;
40 import android.util.Log;
41 
42 import com.android.car.test.TestPropertyAsyncCallback;
43 import com.android.compatibility.common.util.ApiTest;
44 
45 import org.junit.After;
46 import org.junit.Before;
47 import org.junit.Test;
48 
49 import java.util.ArrayList;
50 import java.util.List;
51 import java.util.Set;
52 import java.util.concurrent.Executor;
53 
54 public final class CarPropertyManagerTest extends CarApiTestBase {
55     private static final int EXPECTED_VENDOR_ERROR_CODE = 0x00ab;
56     private static final int NUMBER_OF_TEST_CODES = 0x2000;
57     // 557862912
58     private static final int STARTING_TEST_CODES = 0x3000 | VehiclePropertyGroup.VENDOR
59             | VehicleArea.GLOBAL | VehiclePropertyType.INT32;
60     private static final int END_TEST_CODES = 0x3000 + NUMBER_OF_TEST_CODES
61             | VehiclePropertyGroup.VENDOR | VehicleArea.GLOBAL | VehiclePropertyType.INT32;
62     private static final String TAG = CarPropertyManagerTest.class.getSimpleName();
63 
64     private final HandlerThread mHandlerThread = new HandlerThread(getClass().getSimpleName());
65 
66     private CarPropertyManager mCarPropertyManager;
67     private CarTestManager mTestManager;
68     private Binder mToken;
69     private Handler mHandler;
70 
71     @Before
setUp()72     public void setUp() throws Exception {
73         mHandlerThread.start();
74         mHandler = new Handler(mHandlerThread.getLooper());
75         mCarPropertyManager = (CarPropertyManager) getCar().getCarManager(Car.PROPERTY_SERVICE);
76         assertThat(mCarPropertyManager).isNotNull();
77         mTestManager = getCarService(Car.TEST_SERVICE);
78         mToken = new Binder("stop_car_service");
79     }
80 
81     @After
tearDown()82     public void tearDown() throws Exception {
83         mHandlerThread.quitSafely();
84     }
85 
86     @ApiTest(apis = {"android.car.hardware.property.CarInternalErrorException#getVendorErrorCode"})
87     @Test
testGetProperty_withVendorPropertyId_throws()88     public void testGetProperty_withVendorPropertyId_throws() {
89         List<CarPropertyConfig> carPropertyConfigList = mCarPropertyManager.getPropertyList(
90                 new ArraySet(List.of(VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING)));
91         assumeTrue("VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING is supported",
92                 !carPropertyConfigList.isEmpty());
93         CarInternalErrorException thrown = assertThrows(CarInternalErrorException.class, () ->
94                 mCarPropertyManager.getProperty(VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING,
95                         /* areaId = */ 0));
96 
97         assertThat(thrown.getVendorErrorCode()).isEqualTo(EXPECTED_VENDOR_ERROR_CODE);
98     }
99 
100     @ApiTest(apis = {"android.car.hardware.property.CarInternalErrorException#getVendorErrorCode"})
101     @Test
testSetProperty_withVendorPropertyId_throws()102     public void testSetProperty_withVendorPropertyId_throws() {
103         List<CarPropertyConfig> carPropertyConfigList = mCarPropertyManager.getPropertyList(
104                 new ArraySet(List.of(VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING)));
105         assumeTrue("VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING is supported",
106                 !carPropertyConfigList.isEmpty());
107         CarInternalErrorException thrown = assertThrows(CarInternalErrorException.class,
108                 () -> mCarPropertyManager.setProperty(Integer.class,
109                         VENDOR_PROPERTY_FOR_ERROR_CODE_TESTING, /* areaId = */ 0, /* val= */ 0));
110 
111         assertThat(thrown.getVendorErrorCode()).isEqualTo(EXPECTED_VENDOR_ERROR_CODE);
112     }
113 
114     @ApiTest(apis = {"android.car.hardware.property.CarPropertyManager#getPropertyList()"})
115     @Test
testGetPropertyListWithLargeNumberOfConfigs()116     public void testGetPropertyListWithLargeNumberOfConfigs() throws Exception {
117         List<CarPropertyConfig> carPropertyConfigsListBeforeGenerating =
118                 mCarPropertyManager.getPropertyList();
119         Set<Integer> resultSet = new ArraySet<>();
120         for (int i = 0; i < carPropertyConfigsListBeforeGenerating.size(); i++) {
121             resultSet.add(carPropertyConfigsListBeforeGenerating.get(i).getPropertyId());
122         }
123         boolean isDebugCommandSupported = false;
124         try {
125             for (int i = STARTING_TEST_CODES; i < END_TEST_CODES; i++) {
126                 assertThat(i).isNotIn(resultSet);
127             }
128             Log.d(TAG, "Stopping car service for test");
129             mTestManager.stopCarService(mToken);
130             String result = CarApiTestBase.executeShellCommand(
131                     "dumpsys car_service gen-test-vendor-configs");
132             Log.d(TAG, "Starting car service for test");
133             mTestManager.startCarService(mToken);
134 
135             List<CarPropertyConfig> carPropertyConfigsList = mCarPropertyManager.getPropertyList();
136             resultSet = new ArraySet<>();
137             for (int i = 0; i < carPropertyConfigsList.size(); i++) {
138                 resultSet.add(carPropertyConfigsList.get(i).getPropertyId());
139             }
140             isDebugCommandSupported = result.equals("successfully generated vendor configs\n");
141             assumeTrue("successfully generated vendor configs, VHAL gen-test-vendor-configs "
142                             + "debug command is supported",
143                     isDebugCommandSupported);
144             for (int i = STARTING_TEST_CODES; i < END_TEST_CODES; i++) {
145                 assertThat(i).isIn(resultSet);
146             }
147         } finally {
148             restoreCarService(isDebugCommandSupported);
149         }
150     }
151 
152     @ApiTest(apis = {"android.car.hardware.property.CarPropertyManager#setPropertiesAsync"
153             + "(List, long, CancellationSignal, Executor, SetPropertyCallback)"})
154     @Test
testSetPropertiesAsyncWithLargeNumberRequests()155     public void testSetPropertiesAsyncWithLargeNumberRequests() throws Exception {
156         boolean isDebugCommandSupported = false;
157         try {
158             Log.d(TAG, "Stopping car service for test");
159             mTestManager.stopCarService(mToken);
160             String result = CarApiTestBase.executeShellCommand(
161                     "dumpsys car_service gen-test-vendor-configs");
162             Log.d(TAG, "Starting car service for test");
163             mTestManager.startCarService(mToken);
164             isDebugCommandSupported = result.equals("successfully generated vendor configs\n");
165             assumeTrue("successfully generated vendor configs, VHAL gen-test-vendor-configs "
166                             + "debug command is supported",
167                     isDebugCommandSupported);
168             Executor callbackExecutor = new HandlerExecutor(mHandler);
169             Set<Integer> setPropertyIds = new ArraySet<>();
170             List<CarPropertyManager.SetPropertyRequest<?>> setPropertyRequests = new ArrayList<>();
171 
172             for (int i = STARTING_TEST_CODES; i < END_TEST_CODES; i++) {
173                 CarPropertyManager.SetPropertyRequest setRequest =
174                         mCarPropertyManager.generateSetPropertyRequest(
175                                 i, /* areaId= */ 0, /* value= */ 10);
176                 setRequest.setWaitForPropertyUpdate(false);
177                 setPropertyRequests.add(setRequest);
178                 setPropertyIds.add(setRequest.getRequestId());
179             }
180             TestPropertyAsyncCallback callback = new TestPropertyAsyncCallback(
181                     setPropertyIds);
182             mCarPropertyManager.setPropertiesAsync(setPropertyRequests, /* timeoutInMs= */ 10000,
183                     /* cancellationSignal= */ null, callbackExecutor, callback);
184 
185             callback.waitAndFinish(/* timeoutInMs= */ 30000);
186             assertThat(callback.getTestErrors()).isEmpty();
187             List<CarPropertyManager.SetPropertyResult> results = callback.getSetResultList();
188             assertThat(results).hasSize(NUMBER_OF_TEST_CODES);
189             assertThat(callback.getErrorList().size()).isEqualTo(0);
190         } finally {
191             Log.d(TAG, "restoring car service");
192             restoreCarService(isDebugCommandSupported);
193         }
194     }
195 
196     @ApiTest(apis = {"android.car.hardware.property.CarPropertyManager#getPropertiesAsync"
197             + "(List, long, CancellationSignal, Executor, GetPropertyCallback)"})
198     @Test
testGetPropertiesAsyncWithLargeNumberRequests()199     public void testGetPropertiesAsyncWithLargeNumberRequests() throws Exception {
200         boolean isDebugCommandSupported = false;
201         try {
202             Log.d(TAG, "Stopping car service for test");
203             mTestManager.stopCarService(mToken);
204             String result = CarApiTestBase.executeShellCommand(
205                     "dumpsys car_service gen-test-vendor-configs");
206             isDebugCommandSupported = result.equals("successfully generated vendor configs\n");
207             Log.d(TAG, "Starting car service for test");
208             mTestManager.startCarService(mToken);
209             assumeTrue("successfully generated vendor configs, VHAL gen-test-vendor-configs "
210                             + "debug command is supported",
211                     isDebugCommandSupported);
212 
213             Executor callbackExecutor = new HandlerExecutor(mHandler);
214             Set<Integer> getPropertyIds = new ArraySet<>();
215             List<CarPropertyManager.GetPropertyRequest> getPropertyRequests = new ArrayList<>();
216 
217             for (int i = STARTING_TEST_CODES; i < END_TEST_CODES; i++) {
218                 CarPropertyManager.GetPropertyRequest getRequest =
219                         mCarPropertyManager.generateGetPropertyRequest(
220                                 i, /* areaId= */ 0);
221                 getPropertyRequests.add(getRequest);
222                 getPropertyIds.add(getRequest.getRequestId());
223             }
224             TestPropertyAsyncCallback callback = new TestPropertyAsyncCallback(
225                     getPropertyIds);
226             mCarPropertyManager.getPropertiesAsync(getPropertyRequests, /* timeoutInMs= */ 10000,
227                     /* cancellationSignal= */ null, callbackExecutor, callback);
228 
229             callback.waitAndFinish(/* timeoutInMs= */ 30000);
230             assertThat(callback.getTestErrors()).isEmpty();
231             List<CarPropertyManager.GetPropertyResult<?>> results = callback.getGetResultList();
232             assertThat(results.size()).isEqualTo(NUMBER_OF_TEST_CODES);
233             assertThat(callback.getErrorList()).isEmpty();
234         } finally {
235             Log.d(TAG, "restoring car service");
236             restoreCarService(isDebugCommandSupported);
237         }
238     }
239 
restoreCarService(boolean isDebugCommandSupported)240     private void restoreCarService(boolean isDebugCommandSupported) throws Exception {
241         Binder restartCarService = new Binder("restart_car_service_after_test");
242         try {
243             Log.d(TAG, "Stopping car service for test");
244             mTestManager.stopCarService(restartCarService);
245             if (isDebugCommandSupported) {
246                 String result = CarApiTestBase.executeShellCommand(
247                         "dumpsys car_service restore-vendor-configs");
248                 assertThat(result.equals("successfully restored vendor configs\n")).isTrue();
249             }
250             Log.d(TAG, "Starting car service for test");
251         } finally {
252             mTestManager.startCarService(restartCarService);
253         }
254     }
255 }
256