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.car.hal; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.anyBoolean; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.doAnswer; 24 import static org.mockito.Mockito.never; 25 import static org.mockito.Mockito.reset; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.car.evs.CarEvsManager; 30 import android.hardware.automotive.vehicle.EvsServiceState; 31 import android.hardware.automotive.vehicle.EvsServiceType; 32 import android.hardware.automotive.vehicle.VehicleProperty; 33 34 import com.android.car.hal.test.AidlVehiclePropConfigBuilder; 35 36 import com.google.common.collect.ImmutableList; 37 import com.google.common.collect.ImmutableSet; 38 39 import org.junit.After; 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 import org.mockito.ArgumentCaptor; 44 import org.mockito.Captor; 45 import org.mockito.Mock; 46 import org.mockito.junit.MockitoJUnitRunner; 47 48 import java.util.ArrayList; 49 import java.util.Collection; 50 import java.util.List; 51 import java.util.Set; 52 import java.util.stream.IntStream; 53 54 @RunWith(MockitoJUnitRunner.class) 55 public class EvsHalServiceTest { 56 @Mock VehicleHal mVehicleHal; 57 @Mock EvsHalService.EvsHalEventListener mListener; 58 @Captor ArgumentCaptor<HalPropValue> mPropCaptor; 59 60 private static final HalPropConfig EVS_SERVICE_REQUEST = 61 new AidlHalPropConfig( 62 AidlVehiclePropConfigBuilder.newBuilder(VehicleProperty.EVS_SERVICE_REQUEST) 63 .build()); 64 65 private EvsHalService mEvsHalService; 66 67 private static final int TRUE = 1; 68 private static final int FALSE = 0; 69 private static final HalPropValueBuilder PROP_VALUE_BUILDER = new HalPropValueBuilder( 70 /*isAidl=*/true); 71 getIntValues(HalPropValue value)72 private List<Integer> getIntValues(HalPropValue value) { 73 List<Integer> intValues = new ArrayList<Integer>(); 74 for (int i = 0; i < value.getInt32ValuesSize(); i++) { 75 intValues.add(value.getInt32Value(i)); 76 } 77 return intValues; 78 } 79 80 @Before setUp()81 public void setUp() { 82 when(mVehicleHal.getHalPropValueBuilder()).thenReturn(PROP_VALUE_BUILDER); 83 mEvsHalService = new EvsHalService(mVehicleHal); 84 mEvsHalService.init(); 85 } 86 87 @After tearDown()88 public void tearDown() { 89 mEvsHalService.release(); 90 mEvsHalService = null; 91 } 92 93 @Test takesEvsServiceRequestProperty()94 public void takesEvsServiceRequestProperty() { 95 Set<HalPropConfig> offeredProps = ImmutableSet.of( 96 EVS_SERVICE_REQUEST); 97 98 mEvsHalService.takeProperties(offeredProps); 99 100 assertThat(mEvsHalService.isEvsServiceRequestSupported()).isTrue(); 101 } 102 103 @Test requestToStartRearviewViaEvsServiceRequest()104 public void requestToStartRearviewViaEvsServiceRequest() { 105 subscribeListener(ImmutableSet.of(EVS_SERVICE_REQUEST)); 106 107 List<Integer> events = new ArrayList<>(); 108 doAnswer(invocation -> { 109 events.add(invocation.getArgument(0)); 110 events.add(invocation.getArgument(1) ? TRUE : FALSE); 111 return null; 112 }).when(mListener).onEvent(anyInt(), anyBoolean()); 113 114 dispatchEvsServiceRequest(EvsServiceType.REARVIEW, EvsServiceState.ON); 115 116 assertThat(events.get(0)).isEqualTo(CarEvsManager.SERVICE_TYPE_REARVIEW); 117 assertThat(events.get(1)).isEqualTo(TRUE); 118 } 119 120 @Test requestToStopRearviewViaEvsServiceRequest()121 public void requestToStopRearviewViaEvsServiceRequest() { 122 subscribeListener(ImmutableSet.of(EVS_SERVICE_REQUEST)); 123 124 List<Integer> events = new ArrayList<>(); 125 doAnswer(invocation -> { 126 events.add(invocation.getArgument(0)); 127 events.add(invocation.getArgument(1) ? TRUE : FALSE); 128 return null; 129 }).when(mListener).onEvent(anyInt(), anyBoolean()); 130 131 dispatchEvsServiceRequest(EvsServiceType.REARVIEW, EvsServiceState.OFF); 132 133 assertThat(events.get(0)).isEqualTo(CarEvsManager.SERVICE_TYPE_REARVIEW); 134 assertThat(events.get(1)).isEqualTo(FALSE); 135 } 136 137 @Test handleInvalidHalEvents()138 public void handleInvalidHalEvents() { 139 subscribeListener(ImmutableSet.of(EVS_SERVICE_REQUEST)); 140 HalPropValue v = PROP_VALUE_BUILDER.build(VehicleProperty.EVS_SERVICE_REQUEST, 141 /*areaId=*/0); 142 143 // Not type, no state. 144 mEvsHalService.onHalEvents(ImmutableList.of(v)); 145 verify(mListener, never()).onEvent(anyInt(), anyBoolean()); 146 147 // Not state. 148 v = PROP_VALUE_BUILDER.build(VehicleProperty.EVS_SERVICE_REQUEST, /*areaId=*/0, 149 EvsServiceType.REARVIEW); 150 mEvsHalService.onHalEvents(ImmutableList.of(v)); 151 verify(mListener, never()).onEvent(anyInt(), anyBoolean()); 152 } 153 154 @Test getAllSupportedProperties()155 public void getAllSupportedProperties() { 156 subscribeListener(ImmutableSet.of(EVS_SERVICE_REQUEST)); 157 158 int[] supported = mEvsHalService.getAllSupportedProperties(); 159 assertThat(supported.length > 0).isTrue(); 160 assertThat(IntStream.of(supported).anyMatch(x -> x == VehicleProperty.EVS_SERVICE_REQUEST)) 161 .isTrue(); 162 } 163 164 @Test testUpdateCameraServiceCurrentState()165 public void testUpdateCameraServiceCurrentState() { 166 int[] states = {CarEvsManager.SERVICE_STATE_ACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 167 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 168 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 169 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE}; 170 171 mEvsHalService.reportCurrentState(states); 172 173 verify(mVehicleHal).set(mPropCaptor.capture()); 174 HalPropValue prop = mPropCaptor.getValue(); 175 assertThat(prop.getPropId()).isEqualTo(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE); 176 assertThat(getIntValues(prop)).containsExactly( 177 CarEvsManager.SERVICE_STATE_ACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 178 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 179 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE, 180 CarEvsManager.SERVICE_STATE_INACTIVE, CarEvsManager.SERVICE_STATE_INACTIVE); 181 } 182 dispatchEvsServiceRequest(int type, int state)183 private void dispatchEvsServiceRequest(int type, int state) { 184 mEvsHalService.onHalEvents(ImmutableList.of(buildEvsServiceRequestProp(type, state))); 185 } 186 buildEvsServiceRequestProp(int type, int state)187 private HalPropValue buildEvsServiceRequestProp(int type, int state) { 188 return PROP_VALUE_BUILDER.build(VehicleProperty.EVS_SERVICE_REQUEST, /*areaId=*/0, 189 new int[]{type, state}); 190 } 191 subscribeListener(Collection<HalPropConfig> properties)192 private void subscribeListener(Collection<HalPropConfig> properties) { 193 reset(mListener); 194 mEvsHalService.takeProperties(properties); 195 mEvsHalService.setListener(mListener); 196 197 for (HalPropConfig config : properties) { 198 verify(mVehicleHal).subscribePropertySafe(mEvsHalService, config.getPropId()); 199 } 200 } 201 } 202