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 package com.android.car.test;
     17 
     18 import android.car.Car;
     19 import android.car.hardware.radio.CarRadioEvent;
     20 import android.car.hardware.radio.CarRadioManager;
     21 import android.car.hardware.radio.CarRadioManager.CarRadioEventListener;
     22 import android.car.hardware.radio.CarRadioPreset;
     23 import android.hardware.radio.RadioManager;
     24 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
     25 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
     26 import android.os.SystemClock;
     27 import android.test.suitebuilder.annotation.MediumTest;
     28 import android.util.Log;
     29 
     30 import com.google.android.collect.Lists;
     31 
     32 import com.android.car.vehiclehal.VehiclePropValueBuilder;
     33 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
     34 
     35 import java.util.HashMap;
     36 import java.util.concurrent.Semaphore;
     37 import java.util.concurrent.TimeUnit;
     38 
     39 @MediumTest
     40 public class CarRadioManagerTest extends MockedCarTestBase {
     41 
     42     private static final String TAG = CarRadioManagerTest.class.getSimpleName();
     43 
     44     // Use this semaphore to block until the callback is heard of.
     45     private Semaphore mAvailable;
     46 
     47     private static final int NUM_PRESETS = 2;
     48     private final HashMap<Integer, CarRadioPreset> mRadioPresets = new HashMap<>();
     49 
     50     private CarRadioManager mCarRadioManager;
     51 
     52     private class RadioPresetPropertyHandler implements VehicleHalPropertyHandler {
     53         public RadioPresetPropertyHandler() { }
     54 
     55         @Override
     56         public synchronized void onPropertySet(VehiclePropValue value) {
     57             assertEquals(value.prop, VehicleProperty.RADIO_PRESET);
     58 
     59             Integer[] valueList = new Integer[4];
     60             value.value.int32Values.toArray(valueList);
     61             assertFalse(
     62                 "Index out of range: " + valueList[0] + " (0, " + NUM_PRESETS + ")",
     63                 valueList[0] < 1);
     64             assertFalse(
     65                 "Index out of range: " + valueList[0] + " (0, " + NUM_PRESETS + ")",
     66                 valueList[0] > NUM_PRESETS);
     67 
     68             CarRadioPreset preset =
     69                 new CarRadioPreset(valueList[0], valueList[1], valueList[2], valueList[3]);
     70             mRadioPresets.put(valueList[0], preset);
     71 
     72             // The test case must be waiting for the semaphore, if not we should throw exception.
     73             if (mAvailable.availablePermits() != 0) {
     74                 Log.d(TAG, "Lock was free, should have been locked.");
     75             }
     76             mAvailable.release();
     77         }
     78 
     79         @Override
     80         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
     81             assertEquals(value.prop, VehicleProperty.RADIO_PRESET);
     82 
     83             Integer[] valueList = new Integer[4];
     84             value.value.int32Values.toArray(valueList);
     85 
     86             // Get the actual preset.
     87             if (valueList[0] < 1 || valueList[0] > NUM_PRESETS) {
     88                 // VNS will call get method when subscribe is called, just return an empty
     89                 // value.
     90                 return value;
     91             }
     92             CarRadioPreset preset = mRadioPresets.get(valueList[0]);
     93             return VehiclePropValueBuilder.newBuilder(VehicleProperty.RADIO_PRESET)
     94                     .setTimestamp(SystemClock.elapsedRealtimeNanos())
     95                     .addIntValue(
     96                             preset.getPresetNumber(),
     97                             preset.getBand(),
     98                             preset.getChannel(),
     99                             preset.getSubChannel())
    100                     .build();
    101         }
    102 
    103         @Override
    104         public synchronized void onPropertySubscribe(int property, int zones, float sampleRate) {
    105             Log.d(TAG, "onPropertySubscribe property: " + property + " rate: " + sampleRate);
    106             if (mAvailable.availablePermits() != 0) {
    107                 Log.d(TAG, "Lock was free, should have been locked.");
    108                 return;
    109             }
    110             mAvailable.release();
    111         }
    112 
    113         @Override
    114         public synchronized void onPropertyUnsubscribe(int property) {
    115         }
    116     }
    117 
    118     private class EventListener implements CarRadioEventListener {
    119         public EventListener() { }
    120 
    121         @Override
    122         public void onEvent(CarRadioEvent event) {
    123             // Print the event and release the lock.
    124             Log.d(TAG, event.toString());
    125             if (mAvailable.availablePermits() != 0) {
    126                 Log.e(TAG, "Lock should be taken.");
    127                 // Let the timeout fail the test here.
    128                 return;
    129             }
    130             mAvailable.release();
    131         }
    132     }
    133 
    134     @Override
    135     protected synchronized void configureMockedHal() {
    136         addProperty(VehicleProperty.RADIO_PRESET, new RadioPresetPropertyHandler())
    137                 .setConfigArray(Lists.newArrayList(NUM_PRESETS));
    138     }
    139 
    140     @Override
    141     protected void setUp() throws Exception {
    142         super.setUp();
    143         mAvailable = new Semaphore(0);
    144         mCarRadioManager = (CarRadioManager) getCar().getCarManager(Car.RADIO_SERVICE);
    145     }
    146 
    147     public void testPresetCount() throws Exception {
    148         int presetCount = mCarRadioManager.getPresetCount();
    149         assertEquals("Preset count not same.", NUM_PRESETS, presetCount);
    150     }
    151 
    152     public void testSetAndGetPreset() throws Exception {
    153         // Create a preset.
    154         CarRadioPreset preset = new CarRadioPreset(1, RadioManager.BAND_FM, 1234, -1);
    155         assertEquals("Lock should be freed by now.", 0, mAvailable.availablePermits());
    156         // mAvailable.acquire(1);
    157         mCarRadioManager.setPreset(preset);
    158 
    159         // Wait for acquire to be available again, fail if timeout.
    160         boolean success = mAvailable.tryAcquire(5L, TimeUnit.SECONDS);
    161         assertEquals("Could not finish setting, timeout!", true, success);
    162 
    163         // Test that get preset gives you the same element.
    164         assertEquals(preset, mCarRadioManager.getPreset(1));
    165     }
    166 
    167     public void testSubscribe() throws Exception {
    168         EventListener listener = new EventListener();
    169         assertEquals("Lock should be freed by now.", 0, mAvailable.availablePermits());
    170         mCarRadioManager.registerListener(listener);
    171 
    172         // Wait for acquire to be available again, fail if timeout.
    173         boolean success = mAvailable.tryAcquire(5L, TimeUnit.SECONDS);
    174         assertEquals("addListener timeout", true, success);
    175 
    176         // Inject an event and wait for its callback in onPropertySet.
    177         CarRadioPreset preset = new CarRadioPreset(2, RadioManager.BAND_AM, 4321, -1);
    178 
    179         VehiclePropValue v = VehiclePropValueBuilder.newBuilder(VehicleProperty.RADIO_PRESET)
    180                 .setTimestamp(SystemClock.elapsedRealtimeNanos())
    181                 .addIntValue(
    182                         preset.getPresetNumber(),
    183                         preset.getBand(),
    184                         preset.getChannel(),
    185                         preset.getSubChannel())
    186                 .build();
    187         getMockedVehicleHal().injectEvent(v);
    188 
    189         success = mAvailable.tryAcquire(5L, TimeUnit.SECONDS);
    190         assertEquals("injectEvent, onEvent timeout!", true, success);
    191     }
    192 }
    193