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