blob: 053bab73f1d5cb075dae61b741f42f1d6d52e751 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.test;
import android.annotation.ArrayRes;
import android.car.VehicleAreaType;
import android.car.annotation.FutureFeature;
import android.car.vms.VmsLayer;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode;
import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex;
import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex;
import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
import com.android.car.R;
import com.android.car.vehiclehal.VehiclePropValueBuilder;
import com.android.car.vehiclehal.test.MockedVehicleHal;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@FutureFeature
@MediumTest
public class VmsPublisherClientServiceTest extends MockedCarTestBase {
private static final String TAG = "VmsPublisherTest";
private static final int MOCK_PUBLISHER_LAYER_ID = 12;
private static final int MOCK_PUBLISHER_LAYER_VERSION = 34;
private static final int MOCK_PUBLISHER_LAYER_SUBTYPE = 56;
public static final int MOCK_PUBLISHER_ID = 1234;
public static final VmsLayer MOCK_PUBLISHER_LAYER =
new VmsLayer(MOCK_PUBLISHER_LAYER_ID,
MOCK_PUBLISHER_LAYER_SUBTYPE,
MOCK_PUBLISHER_LAYER_VERSION);
public static final byte[] PAYLOAD = new byte[]{1, 1, 2, 3, 5, 8, 13};
private HalHandler mHalHandler;
// Used to block until the HAL property is updated in HalHandler.onPropertySet.
private Semaphore mHalHandlerSemaphore;
@Override
protected synchronized void configureMockedHal() {
mHalHandler = new HalHandler();
addProperty(VehicleProperty.VEHICLE_MAP_SERVICE, mHalHandler)
.setChangeMode(VehiclePropertyChangeMode.ON_CHANGE)
.setAccess(VehiclePropertyAccess.READ_WRITE)
.setSupportedAreas(VehicleAreaType.VEHICLE_AREA_TYPE_NONE);
}
/**
* Creates a context with the resource vmsPublisherClients overridden. The overridden value
* contains the name of the test service defined also in this test package.
*/
@Override
protected Context getCarServiceContext() throws PackageManager.NameNotFoundException {
Context context = getContext()
.createPackageContext("com.android.car", Context.CONTEXT_IGNORE_SECURITY);
Resources resources = new Resources(context.getAssets(),
context.getResources().getDisplayMetrics(),
context.getResources().getConfiguration()) {
@Override
public String[] getStringArray(@ArrayRes int id) throws NotFoundException {
if (id == R.array.vmsPublisherClients) {
return new String[]{"com.android.car.test/.SimpleVmsPublisherClientService"};
}
return super.getStringArray(id);
}
};
ContextWrapper wrapper = new ContextWrapper(context) {
@Override
public Resources getResources() {
return resources;
}
};
return wrapper;
}
private VehiclePropValue getHalSubscriptionRequest() {
return VehiclePropValueBuilder.newBuilder(VehicleProperty.VEHICLE_MAP_SERVICE)
.addIntValue(VmsMessageType.SUBSCRIBE)
.addIntValue(MOCK_PUBLISHER_LAYER_ID)
.addIntValue(MOCK_PUBLISHER_LAYER_SUBTYPE)
.addIntValue(MOCK_PUBLISHER_LAYER_VERSION)
.build();
}
@Override
protected void setUp() throws Exception {
if (!VmsTestUtils.canRunTest(TAG)) return;
/**
* First init the semaphore, setUp will start a series of events that will ultimately
* update the HAL layer and release this semaphore.
*/
mHalHandlerSemaphore = new Semaphore(0);
super.setUp();
// Inject a subscribe event which simulates the HAL is subscribed to the Mock Publisher.
MockedVehicleHal mHal = getMockedVehicleHal();
mHal.injectEvent(getHalSubscriptionRequest());
}
@Override
protected synchronized void tearDown() throws Exception {
if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
/**
* The method setUp initializes all the Car services, including the VmsPublisherService.
* The VmsPublisherService will start and configure its list of clients. This list was
* overridden in the method getCarServiceContext.
* Therefore, only SimpleVmsPublisherClientService will be started.
* The service SimpleVmsPublisherClientService will publish one message, which is validated in
* this test.
*/
public void testPublish() throws Exception {
if (!VmsTestUtils.canRunTest(TAG)) return;
//TODO: This test is using minial synchronisation between clients.
// If more complexity is added this may result in publisher
// publishing before the subscriber subscribed, in which case
// the semaphore will not be released.
assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS));
VehiclePropValue.RawValue rawValue = mHalHandler.getValue().value;
int messageType = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.MESSAGE_TYPE);
int layerId = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_TYPE);
int layerVersion = rawValue.int32Values.get(VmsMessageWithLayerIntegerValuesIndex.LAYER_VERSION);
byte[] payload = new byte[rawValue.bytes.size()];
for (int i = 0; i < rawValue.bytes.size(); ++i) {
payload[i] = rawValue.bytes.get(i);
}
assertEquals(VmsMessageType.DATA, messageType);
assertEquals(MOCK_PUBLISHER_LAYER_ID, layerId);
assertEquals(MOCK_PUBLISHER_LAYER_VERSION, layerVersion);
assertTrue(Arrays.equals(PAYLOAD, payload));
}
private class HalHandler implements VehicleHalPropertyHandler {
private VehiclePropValue mValue;
@Override
public synchronized void onPropertySet(VehiclePropValue value) {
mValue = value;
// If this is the data message release the semaphone so the test can continue.
ArrayList<Integer> int32Values = value.value.int32Values;
if (int32Values.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE) ==
VmsMessageType.DATA) {
mHalHandlerSemaphore.release();
}
}
@Override
public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
return mValue != null ? mValue : value;
}
@Override
public synchronized void onPropertySubscribe(int property, int zones, float sampleRate) {
Log.d(TAG, "onPropertySubscribe property " + property + " sampleRate " + sampleRate);
}
@Override
public synchronized void onPropertyUnsubscribe(int property) {
Log.d(TAG, "onPropertyUnSubscribe property " + property);
}
public VehiclePropValue getValue() {
return mValue;
}
}
}