• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.car.Car;
24 import android.car.hardware.CarPropertyValue;
25 import android.car.hardware.cabin.CarCabinManager;
26 import android.car.hardware.cabin.CarCabinManager.CarCabinEventCallback;
27 import android.car.hardware.cabin.CarCabinManager.PropertyId;
28 import android.hardware.automotive.vehicle.V2_0.VehicleAreaDoor;
29 import android.hardware.automotive.vehicle.V2_0.VehicleAreaWindow;
30 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
31 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
32 import android.os.SystemClock;
33 import android.support.test.filters.MediumTest;
34 import android.support.test.runner.AndroidJUnit4;
35 import android.util.Log;
36 import android.util.MutableInt;
37 
38 import com.android.car.vehiclehal.VehiclePropValueBuilder;
39 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
40 
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.HashMap;
45 import java.util.concurrent.CountDownLatch;
46 import java.util.concurrent.Semaphore;
47 import java.util.concurrent.TimeUnit;
48 
49 @RunWith(AndroidJUnit4.class)
50 @MediumTest
51 public class CarCabinManagerTest extends MockedCarTestBase {
52     private static final String TAG = CarCabinManagerTest.class.getSimpleName();
53 
54     // Use this semaphore to block until the callback is heard of.
55     private Semaphore mAvailable;
56 
57     private CarCabinManager mCarCabinManager;
58     private boolean mEventBoolVal;
59     private int mEventIntVal;
60     private int mEventZoneVal;
61 
62     @Override
configureMockedHal()63     protected synchronized void configureMockedHal() {
64         CabinPropertyHandler handler = new CabinPropertyHandler();
65         addProperty(VehicleProperty.DOOR_LOCK, handler)
66                 .addAreaConfig(VehicleAreaDoor.ROW_1_LEFT, 0, 0);
67         addProperty(VehicleProperty.WINDOW_POS, handler)
68                 .addAreaConfig(VehicleAreaWindow.ROW_1_LEFT, 0, 0);
69     }
70 
71     @Override
setUp()72     public void setUp() throws Exception {
73         super.setUp();
74         mAvailable = new Semaphore(0);
75         mCarCabinManager = (CarCabinManager) getCar().getCarManager(Car.CABIN_SERVICE);
76     }
77 
78     // Test a boolean property
79     @Test
testCabinDoorLockOn()80     public void testCabinDoorLockOn() throws Exception {
81         mCarCabinManager.setBooleanProperty(CarCabinManager.ID_DOOR_LOCK,
82                 VehicleAreaDoor.ROW_1_LEFT, true);
83         boolean lock = mCarCabinManager.getBooleanProperty(CarCabinManager.ID_DOOR_LOCK,
84                 VehicleAreaDoor.ROW_1_LEFT);
85         assertTrue(lock);
86 
87         mCarCabinManager.setBooleanProperty(CarCabinManager.ID_DOOR_LOCK,
88                 VehicleAreaDoor.ROW_1_LEFT, false);
89         lock = mCarCabinManager.getBooleanProperty(CarCabinManager.ID_DOOR_LOCK,
90                 VehicleAreaDoor.ROW_1_LEFT);
91         assertFalse(lock);
92     }
93 
94     // Test an integer property
95     @Test
testCabinWindowPos()96     public void testCabinWindowPos() throws Exception {
97         mCarCabinManager.setIntProperty(CarCabinManager.ID_WINDOW_POS,
98                 VehicleAreaWindow.ROW_1_LEFT, 50);
99         int windowPos = mCarCabinManager.getIntProperty(CarCabinManager.ID_WINDOW_POS,
100                 VehicleAreaWindow.ROW_1_LEFT);
101         assertEquals(50, windowPos);
102 
103         mCarCabinManager.setIntProperty(CarCabinManager.ID_WINDOW_POS,
104                 VehicleAreaWindow.ROW_1_LEFT, 25);
105         windowPos = mCarCabinManager.getIntProperty(CarCabinManager.ID_WINDOW_POS,
106                 VehicleAreaWindow.ROW_1_LEFT);
107         assertEquals(25, windowPos);
108     }
109 
110     @Test
testError()111     public void testError() throws Exception {
112         final int PROP = VehicleProperty.DOOR_LOCK;
113         final int AREA = VehicleAreaWindow.ROW_1_LEFT;
114         final int ERR_CODE = 42;
115 
116         CountDownLatch errorLatch = new CountDownLatch(1);
117         MutableInt propertyIdReceived = new MutableInt(0);
118         MutableInt areaIdReceived = new MutableInt(0);
119 
120         mCarCabinManager.registerCallback(new CarCabinEventCallback() {
121             @Override
122             public void onChangeEvent(CarPropertyValue value) {
123 
124             }
125 
126             @Override
127             public void onErrorEvent(@PropertyId int propertyId, int area) {
128                 propertyIdReceived.value = propertyId;
129                 areaIdReceived.value = area;
130                 errorLatch.countDown();
131             }
132         });
133 
134         getMockedVehicleHal().injectError(ERR_CODE, PROP, AREA);
135         assertTrue(errorLatch.await(DEFAULT_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
136         assertEquals(PROP, propertyIdReceived.value);
137         assertEquals(AREA, areaIdReceived.value);
138     }
139 
140 
141     // Test an event
142     @Test
testEvent()143     public void testEvent() throws Exception {
144         mCarCabinManager.registerCallback(new EventListener());
145         // Wait for two events generated on registration
146         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
147         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
148         // Inject a boolean event and wait for its callback in onPropertySet.
149         VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.DOOR_LOCK)
150                 .setAreaId(VehicleAreaDoor.ROW_1_LEFT)
151                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
152                 .addIntValue(1)
153                 .build();
154 
155         assertEquals(0, mAvailable.availablePermits());
156         getMockedVehicleHal().injectEvent(v);
157 
158         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
159         assertTrue(mEventBoolVal);
160         assertEquals(VehicleAreaDoor.ROW_1_LEFT, mEventZoneVal);
161 
162         // Inject an integer event and wait for its callback in onPropertySet.
163         v = VehiclePropValueBuilder.newBuilder(VehicleProperty.WINDOW_POS)
164                 .setAreaId(VehicleAreaWindow.ROW_1_LEFT)
165                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
166                 .addIntValue(75)
167                 .build();
168         assertEquals(0, mAvailable.availablePermits());
169         getMockedVehicleHal().injectEvent(v);
170 
171         assertTrue(mAvailable.tryAcquire(2L, TimeUnit.SECONDS));
172         assertEquals(mEventIntVal, 75);
173         assertEquals(VehicleAreaWindow.ROW_1_LEFT, mEventZoneVal);
174     }
175 
176 
177     private class CabinPropertyHandler implements VehicleHalPropertyHandler {
178         HashMap<Integer, VehiclePropValue> mMap = new HashMap<>();
179 
180         @Override
onPropertySet(VehiclePropValue value)181         public synchronized void onPropertySet(VehiclePropValue value) {
182             mMap.put(value.prop, value);
183         }
184 
185         @Override
onPropertyGet(VehiclePropValue value)186         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
187             VehiclePropValue currentValue = mMap.get(value.prop);
188             // VNS will call get method when subscribe is called, just return empty value.
189             return currentValue != null ? currentValue : value;
190         }
191 
192         @Override
onPropertySubscribe(int property, float sampleRate)193         public synchronized void onPropertySubscribe(int property, float sampleRate) {
194             Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate);
195             if (mMap.get(property) == null) {
196                 Log.d(TAG, "onPropertySubscribe add dummy property: " + property);
197                 VehiclePropValue dummyValue = VehiclePropValueBuilder.newBuilder(property)
198                         .setAreaId(VehicleAreaDoor.ROW_1_LEFT)
199                         .setTimestamp(SystemClock.elapsedRealtimeNanos())
200                         .addIntValue(1)
201                         .build();
202                 mMap.put(property, dummyValue);
203             }
204         }
205 
206         @Override
onPropertyUnsubscribe(int property)207         public synchronized void onPropertyUnsubscribe(int property) {
208             Log.d(TAG, "onPropertyUnSubscribe property " + property);
209         }
210     }
211 
212     private class EventListener implements CarCabinEventCallback {
EventListener()213         EventListener() { }
214 
215         @Override
onChangeEvent(final CarPropertyValue value)216         public void onChangeEvent(final CarPropertyValue value) {
217             Log.d(TAG, "onChangeEvent: "  + value);
218             Object o = value.getValue();
219             mEventZoneVal = value.getAreaId();
220 
221             if (o instanceof Integer) {
222                 mEventIntVal = (Integer) o;
223             } else if (o instanceof Boolean) {
224                 mEventBoolVal = (Boolean) o;
225             } else {
226                 Log.e(TAG, "onChangeEvent:  Unknown instance type = " + o.getClass().getName());
227             }
228             mAvailable.release();
229         }
230 
231         @Override
onErrorEvent(final int propertyId, final int zone)232         public void onErrorEvent(final int propertyId, final int zone) {
233             Log.d(TAG, "Error:  propertyId=" + propertyId + "  zone=" + zone);
234         }
235     }
236 }
237