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.hvac.CarHvacManager; 21 import android.car.hardware.hvac.CarHvacManager.CarHvacEventListener; 22 import android.car.hardware.hvac.CarHvacManager.HvacPropertyId; 23 import android.car.hardware.CarPropertyValue; 24 import android.car.test.VehicleHalEmulator; 25 import android.test.suitebuilder.annotation.MediumTest; 26 import android.util.Log; 27 28 import com.android.car.vehiclenetwork.VehicleNetworkConsts; 29 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess; 30 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropChangeMode; 31 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType; 32 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleWindow; 33 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZone; 34 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue; 35 import com.android.car.vehiclenetwork.VehiclePropConfigUtil; 36 import com.android.car.vehiclenetwork.VehiclePropValueUtil; 37 38 import java.util.HashMap; 39 import java.util.concurrent.Semaphore; 40 import java.util.concurrent.TimeUnit; 41 42 @MediumTest 43 public class CarHvacManagerTest extends MockedCarTestBase { 44 private static final String TAG = CarHvacManagerTest.class.getSimpleName(); 45 46 // Use this semaphore to block until the callback is heard of. 47 private Semaphore mAvailable; 48 49 private CarHvacManager mCarHvacManager; 50 private boolean mEventBoolVal; 51 private float mEventFloatVal; 52 private int mEventIntVal; 53 private int mEventZoneVal; 54 55 @Override 56 protected void setUp() throws Exception { 57 super.setUp(); 58 mAvailable = new Semaphore(0); 59 HvacPropertyHandler handler = new HvacPropertyHandler(); 60 getVehicleHalEmulator().addProperty( 61 VehiclePropConfigUtil.createZonedProperty( 62 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_DEFROSTER, 63 VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, 64 VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, 65 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN, 66 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD, 67 0), handler); 68 getVehicleHalEmulator().addProperty( 69 VehiclePropConfigUtil.createZonedProperty( 70 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_SPEED, 71 VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, 72 VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, 73 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32, 74 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 75 0), handler); 76 getVehicleHalEmulator().addProperty( 77 VehiclePropConfigUtil.createZonedProperty( 78 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET, 79 VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE, 80 VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, 81 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT, 82 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 83 0), handler); 84 getVehicleHalEmulator().addProperty( 85 VehiclePropConfigUtil.createZonedProperty( 86 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT, 87 VehiclePropAccess.VEHICLE_PROP_ACCESS_READ, 88 VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_CONTINUOUS, 89 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT, 90 VehicleZone.VEHICLE_ZONE_ROW_1_ALL, 91 0), handler); 92 93 getVehicleHalEmulator().start(); 94 mCarHvacManager = (CarHvacManager) getCar().getCarManager(Car.HVAC_SERVICE); 95 } 96 97 // Test a boolean property 98 public void testHvacRearDefrosterOn() throws Exception { 99 mCarHvacManager.setBooleanProperty(HvacPropertyId.WINDOW_DEFROSTER_ON, 100 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD, true); 101 boolean defrost = mCarHvacManager.getBooleanProperty(HvacPropertyId.WINDOW_DEFROSTER_ON, 102 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD); 103 assertTrue(defrost); 104 105 mCarHvacManager.setBooleanProperty(HvacPropertyId.WINDOW_DEFROSTER_ON, 106 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD, false); 107 defrost = mCarHvacManager.getBooleanProperty(HvacPropertyId.WINDOW_DEFROSTER_ON, 108 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD); 109 assertFalse(defrost); 110 } 111 112 // Test an integer property 113 public void testHvacFanSpeed() throws Exception { 114 mCarHvacManager.setIntProperty(HvacPropertyId.ZONED_FAN_SPEED_SETPOINT, 115 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 15); 116 int speed = mCarHvacManager.getIntProperty(HvacPropertyId.ZONED_FAN_SPEED_SETPOINT, 117 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT); 118 assertEquals(15, speed); 119 120 mCarHvacManager.setIntProperty(HvacPropertyId.ZONED_FAN_SPEED_SETPOINT, 121 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 23); 122 speed = mCarHvacManager.getIntProperty(HvacPropertyId.ZONED_FAN_SPEED_SETPOINT, 123 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT); 124 assertEquals(23, speed); 125 } 126 127 // Test an float property 128 public void testHvacTempSetpoint() throws Exception { 129 mCarHvacManager.setFloatProperty(HvacPropertyId.ZONED_TEMP_SETPOINT, 130 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 70); 131 float temp = mCarHvacManager.getFloatProperty(HvacPropertyId.ZONED_TEMP_SETPOINT, 132 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT); 133 assertEquals(70.0, temp, 0); 134 135 mCarHvacManager.setFloatProperty(HvacPropertyId.ZONED_TEMP_SETPOINT, 136 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, (float) 65.5); 137 temp = mCarHvacManager.getFloatProperty(HvacPropertyId.ZONED_TEMP_SETPOINT, 138 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT); 139 assertEquals(65.5, temp, 0); 140 } 141 142 // Test an event 143 public void testEvent() throws Exception { 144 mCarHvacManager.registerListener(new EventListener()); 145 146 // Inject a boolean event and wait for its callback in onPropertySet. 147 VehiclePropValue v = VehiclePropValueUtil.createZonedBooleanValue( 148 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_DEFROSTER, 149 VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD, true, 0); 150 assertEquals(0, mAvailable.availablePermits()); 151 getVehicleHalEmulator().injectEvent(v); 152 153 assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS)); 154 assertTrue(mEventBoolVal); 155 assertEquals(mEventZoneVal, VehicleWindow.VEHICLE_WINDOW_FRONT_WINDSHIELD); 156 157 // Inject a float event and wait for its callback in onPropertySet. 158 v = VehiclePropValueUtil.createZonedFloatValue( 159 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT, 160 VehicleZone.VEHICLE_ZONE_ROW_1_ALL, 67, 0); 161 assertEquals(0, mAvailable.availablePermits()); 162 getVehicleHalEmulator().injectEvent(v); 163 164 assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS)); 165 assertEquals(mEventFloatVal, 67, 0); 166 assertEquals(mEventZoneVal, VehicleZone.VEHICLE_ZONE_ROW_1_ALL); 167 168 // Inject an integer event and wait for its callback in onPropertySet. 169 v = VehiclePropValueUtil.createZonedIntValue( 170 VehicleNetworkConsts.VEHICLE_PROPERTY_HVAC_FAN_SPEED, 171 VehicleZone.VEHICLE_ZONE_ROW_1_LEFT, 4, 0); 172 assertEquals(0, mAvailable.availablePermits()); 173 getVehicleHalEmulator().injectEvent(v); 174 175 assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS)); 176 assertEquals(mEventIntVal, 4); 177 assertEquals(mEventZoneVal, VehicleZone.VEHICLE_ZONE_ROW_1_LEFT); 178 } 179 180 181 private class HvacPropertyHandler 182 implements VehicleHalEmulator.VehicleHalPropertyHandler { 183 HashMap<Integer, VehiclePropValue> mMap = new HashMap<>(); 184 185 @Override 186 public synchronized void onPropertySet(VehiclePropValue value) { 187 mMap.put(value.getProp(), value); 188 } 189 190 @Override 191 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { 192 return mMap.get(value.getProp()); 193 } 194 195 @Override 196 public synchronized void onPropertySubscribe(int property, float sampleRate, int zones) { 197 Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate); 198 } 199 200 @Override 201 public synchronized void onPropertyUnsubscribe(int property) { 202 Log.d(TAG, "onPropertyUnSubscribe property " + property); 203 } 204 } 205 206 private class EventListener implements CarHvacEventListener { 207 public EventListener() { } 208 209 @Override 210 public void onChangeEvent(final CarPropertyValue value) { 211 Log.d(TAG, "onChangeEvent: " + value); 212 Object o = value.getValue(); 213 mEventZoneVal = value.getAreaId(); 214 215 if (o instanceof Integer) { 216 mEventIntVal = (Integer) o; 217 } else if (o instanceof Float) { 218 mEventFloatVal = (Float) o; 219 } else if (o instanceof Boolean) { 220 mEventBoolVal = (Boolean) o; 221 } 222 mAvailable.release(); 223 } 224 225 @Override 226 public void onErrorEvent(final int propertyId, final int zone) { 227 Log.d(TAG, "Error: propertyId=" + propertyId + " zone=" + zone); 228 } 229 } 230 } 231