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