Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2015 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.test;
     18 
     19 import android.car.Car;
     20 import android.car.hardware.CarPropertyValue;
     21 import android.car.hardware.hvac.CarHvacManager;
     22 import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback;
     23 import android.car.hardware.hvac.CarHvacManager.PropertyId;
     24 import android.hardware.automotive.vehicle.V2_0.VehicleAreaWindow;
     25 import android.hardware.automotive.vehicle.V2_0.VehicleAreaZone;
     26 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
     27 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
     28 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
     29 import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode;
     30 import android.os.SystemClock;
     31 import android.test.suitebuilder.annotation.MediumTest;
     32 import android.util.Log;
     33 import android.util.MutableInt;
     34 
     35 import com.android.car.vehiclehal.VehiclePropValueBuilder;
     36 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
     37 
     38 import java.util.HashMap;
     39 import java.util.concurrent.CountDownLatch;
     40 import java.util.concurrent.Semaphore;
     41 import java.util.concurrent.TimeUnit;
     42 
     43 @MediumTest
     44 public class CarHvacManagerTest extends MockedCarTestBase {
     45     private static final String TAG = CarHvacManagerTest.class.getSimpleName();
     46 
     47     // Use this semaphore to block until the callback is heard of.
     48     private Semaphore mAvailable;
     49 
     50     private CarHvacManager mCarHvacManager;
     51     private boolean mEventBoolVal;
     52     private float mEventFloatVal;
     53     private int mEventIntVal;
     54     private int mEventZoneVal;
     55 
     56     @Override
     57     protected synchronized void configureMockedHal() {
     58         HvacPropertyHandler handler = new HvacPropertyHandler();
     59         addProperty(VehicleProperty.HVAC_DEFROSTER, handler)
     60                 .setSupportedAreas(VehicleAreaWindow.FRONT_WINDSHIELD);
     61         addProperty(VehicleProperty.HVAC_FAN_SPEED, handler)
     62                 .setSupportedAreas(VehicleAreaZone.ROW_1_LEFT);
     63         addProperty(VehicleProperty.HVAC_TEMPERATURE_SET, handler)
     64                 .setSupportedAreas(VehicleAreaZone.ROW_1_LEFT);
     65         addProperty(VehicleProperty.HVAC_TEMPERATURE_CURRENT, handler)
     66                 .setChangeMode(VehiclePropertyChangeMode.CONTINUOUS)
     67                 .setAccess(VehiclePropertyAccess.READ)
     68                 .setSupportedAreas(VehicleAreaZone.ROW_1);
     69     }
     70 
     71     @Override
     72     protected void setUp() throws Exception {
     73         super.setUp();
     74         mAvailable = new Semaphore(0);
     75         mCarHvacManager = (CarHvacManager) getCar().getCarManager(Car.HVAC_SERVICE);
     76     }
     77 
     78     // Test a boolean property
     79     public void testHvacRearDefrosterOn() throws Exception {
     80         mCarHvacManager.setBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
     81                 VehicleAreaWindow.FRONT_WINDSHIELD, true);
     82         boolean defrost = mCarHvacManager.getBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
     83                 VehicleAreaWindow.FRONT_WINDSHIELD);
     84         assertTrue(defrost);
     85 
     86         mCarHvacManager.setBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
     87                 VehicleAreaWindow.FRONT_WINDSHIELD, false);
     88         defrost = mCarHvacManager.getBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
     89                 VehicleAreaWindow.FRONT_WINDSHIELD);
     90         assertFalse(defrost);
     91     }
     92 
     93     // Test an integer property
     94     public void testHvacFanSpeed() throws Exception {
     95         mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
     96                 VehicleAreaZone.ROW_1_LEFT, 15);
     97         int speed = mCarHvacManager.getIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
     98                 VehicleAreaZone.ROW_1_LEFT);
     99         assertEquals(15, speed);
    100 
    101         mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
    102                 VehicleAreaZone.ROW_1_LEFT, 23);
    103         speed = mCarHvacManager.getIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
    104                 VehicleAreaZone.ROW_1_LEFT);
    105         assertEquals(23, speed);
    106     }
    107 
    108     // Test an float property
    109     public void testHvacTempSetpoint() throws Exception {
    110         mCarHvacManager.setFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
    111                 VehicleAreaZone.ROW_1_LEFT, 70);
    112         float temp = mCarHvacManager.getFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
    113                 VehicleAreaZone.ROW_1_LEFT);
    114         assertEquals(70.0, temp, 0);
    115 
    116         mCarHvacManager.setFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
    117                 VehicleAreaZone.ROW_1_LEFT, (float) 65.5);
    118         temp = mCarHvacManager.getFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
    119                 VehicleAreaZone.ROW_1_LEFT);
    120         assertEquals(65.5, temp, 0);
    121     }
    122 
    123     public void testError() throws Exception {
    124         final int PROP = VehicleProperty.HVAC_DEFROSTER;
    125         final int AREA = VehicleAreaWindow.FRONT_WINDSHIELD;
    126         final int ERR_CODE = 42;
    127 
    128         CountDownLatch errorLatch = new CountDownLatch(1);
    129         MutableInt propertyIdReceived = new MutableInt(0);
    130         MutableInt areaIdReceived = new MutableInt(0);
    131 
    132         mCarHvacManager.registerCallback(new CarHvacEventCallback() {
    133             @Override
    134             public void onChangeEvent(CarPropertyValue value) {
    135 
    136             }
    137 
    138             @Override
    139             public void onErrorEvent(@PropertyId int propertyId, int area) {
    140                 propertyIdReceived.value = propertyId;
    141                 areaIdReceived.value = area;
    142                 errorLatch.countDown();
    143             }
    144         });
    145 
    146         getMockedVehicleHal().injectError(ERR_CODE, PROP, AREA);
    147         assertTrue(errorLatch.await(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
    148         assertEquals(PROP, propertyIdReceived.value);
    149         assertEquals(AREA, areaIdReceived.value);
    150     }
    151 
    152     // Test an event
    153     public void testEvent() throws Exception {
    154         mCarHvacManager.registerCallback(new EventListener());
    155 
    156         // Inject a boolean event and wait for its callback in onPropertySet.
    157         VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.HVAC_DEFROSTER)
    158                 .setAreaId(VehicleAreaWindow.FRONT_WINDSHIELD)
    159                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
    160                 .addIntValue(1)
    161                 .build();
    162         assertEquals(0, mAvailable.availablePermits());
    163         getMockedVehicleHal().injectEvent(v);
    164 
    165         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
    166         assertTrue(mEventBoolVal);
    167         assertEquals(mEventZoneVal, VehicleAreaWindow.FRONT_WINDSHIELD);
    168 
    169         // Inject a float event and wait for its callback in onPropertySet.
    170         v = VehiclePropValueBuilder.newBuilder(VehicleProperty.HVAC_TEMPERATURE_CURRENT)
    171                 .setAreaId(VehicleAreaZone.ROW_1)
    172                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
    173                 .addFloatValue(67f)
    174                 .build();
    175         assertEquals(0, mAvailable.availablePermits());
    176         getMockedVehicleHal().injectEvent(v);
    177 
    178         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
    179         assertEquals(67, mEventFloatVal, 0);
    180         assertEquals(VehicleAreaZone.ROW_1, mEventZoneVal);
    181 
    182         // Inject an integer event and wait for its callback in onPropertySet.
    183         v = VehiclePropValueBuilder.newBuilder(VehicleProperty.HVAC_FAN_SPEED)
    184                 .setAreaId(VehicleAreaZone.ROW_1_LEFT)
    185                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
    186                 .addIntValue(4)
    187                 .build();
    188         assertEquals(0, mAvailable.availablePermits());
    189         getMockedVehicleHal().injectEvent(v);
    190 
    191         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
    192         assertEquals(4, mEventIntVal);
    193         assertEquals(VehicleAreaZone.ROW_1_LEFT, mEventZoneVal);
    194     }
    195 
    196     private class HvacPropertyHandler implements VehicleHalPropertyHandler {
    197         HashMap<Integer, VehiclePropValue> mMap = new HashMap<>();
    198 
    199         @Override
    200         public synchronized void onPropertySet(VehiclePropValue value) {
    201             mMap.put(value.prop, value);
    202         }
    203 
    204         @Override
    205         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
    206             VehiclePropValue currentValue = mMap.get(value.prop);
    207             // VNS will call get method when subscribe is called, just return empty value.
    208             return currentValue != null ? currentValue : value;
    209         }
    210 
    211         @Override
    212         public synchronized void onPropertySubscribe(int property, int zones, float sampleRate) {
    213             Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate);
    214         }
    215 
    216         @Override
    217         public synchronized void onPropertyUnsubscribe(int property) {
    218             Log.d(TAG, "onPropertyUnSubscribe property " + property);
    219         }
    220     }
    221 
    222     private class EventListener implements CarHvacEventCallback {
    223         EventListener() { }
    224 
    225         @Override
    226         public void onChangeEvent(final CarPropertyValue value) {
    227             Log.d(TAG, "onChangeEvent: "  + value);
    228             Object o = value.getValue();
    229             mEventZoneVal = value.getAreaId();
    230 
    231             if (o instanceof Integer) {
    232                 mEventIntVal = (Integer) o;
    233             } else if (o instanceof Float) {
    234                 mEventFloatVal = (Float) o;
    235             } else if (o instanceof Boolean) {
    236                 mEventBoolVal = (Boolean) o;
    237             }
    238             mAvailable.release();
    239         }
    240 
    241         @Override
    242         public void onErrorEvent(final int propertyId, final int zone) {
    243             Log.d(TAG, "Error:  propertyId=" + propertyId + "  zone=" + zone);
    244         }
    245     }
    246 }
    247