/* * Copyright (C) 2015 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. */ #define LOG_TAG "VehicleNetworkAudioHelperTest" #include <unistd.h> #include <gtest/gtest.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> #include <utils/threads.h> #include <utils/KeyedVector.h> #include <utils/String8.h> #include <utils/SystemClock.h> #include <vehicle-internal.h> #include <VehicleNetwork.h> #include <VehicleNetworkAudioHelper.h> #include "TestProperties.h" #include "VehicleHalMock.h" #include "VehicleNetworkTestListener.h" namespace android { extern "C" { vehicle_prop_config_t const * getTestPropertiesForAudio(); int getNumTestPropertiesForAudio(); }; class VehicleHalMockForAudioFocus : public VehicleHalMock { public: VehicleHalMockForAudioFocus(sp<VehicleNetwork>& vn) : mVN(vn) { mAudioProperties = new VehiclePropertiesHolder(false /* deleteConfigsInDestructor */); vehicle_prop_config_t const * properties = getTestPropertiesForAudio(); for (int i = 0; i < getNumTestPropertiesForAudio(); i++) { mAudioProperties->getList().push_back(properties + i); } mValueToGet.prop = VEHICLE_PROPERTY_AUDIO_FOCUS; mValueToGet.value_type = VEHICLE_VALUE_TYPE_INT32_VEC4; mValueToGet.value.int32_array[0] = 0; mValueToGet.value.int32_array[1] = 0; mValueToGet.value.int32_array[2] = 0; mValueToGet.value.int32_array[3] = 0; } virtual ~VehicleHalMockForAudioFocus() {}; virtual sp<VehiclePropertiesHolder> onListProperties() { ALOGI("onListProperties"); Mutex::Autolock autoLock(mLock); return mAudioProperties; }; virtual status_t onPropertySet(const vehicle_prop_value_t& value) { ALOGI("onPropertySet 0x%x", value.prop); return NO_ERROR; }; virtual status_t onPropertyGet(vehicle_prop_value_t* value) { ALOGI("onPropertyGet 0x%x", value->prop); Mutex::Autolock autoLock(mLock); if (value->prop == VEHICLE_PROPERTY_AUDIO_FOCUS) { memcpy(value, &mValueToGet, sizeof(vehicle_prop_value_t)); } return NO_ERROR; }; virtual status_t onPropertySubscribe(int32_t property, float /*sampleRate*/, int32_t /*zones*/) { ALOGI("onPropertySubscribe 0x%x", property); return NO_ERROR; }; virtual void onPropertyUnsubscribe(int32_t property) { ALOGI("onPropertySubscribe 0x%x", property); }; void setFocusState(int32_t state, int32_t streams, int32_t extState) { Mutex::Autolock autoLock(mLock); mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_FOCUS] = state; mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_STREAMS] = streams; mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_EXTERNAL_FOCUS_STATE] = extState; mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_AUDIO_CONTEXTS] = 0; mValueToGet.timestamp = elapsedRealtimeNano(); mVN->injectEvent(mValueToGet); } const vehicle_prop_value_t& getCurrentFocus() { Mutex::Autolock autoLock(mLock); return mValueToGet; } private: sp<VehicleNetwork> mVN; mutable Mutex mLock; sp<VehiclePropertiesHolder> mAudioProperties; vehicle_prop_value_t mValueToGet; }; class VehicleNetworkAudioHelperTest : public testing::Test { public: VehicleNetworkAudioHelperTest() : mHalMock(NULL), mVN(NULL), mListener(new VehicleNetworkTestListener()) { } ~VehicleNetworkAudioHelperTest() {} const nsecs_t WAIT_NS = 100000000; protected: virtual void SetUp() { ASSERT_TRUE(mListener.get() != NULL); sp<VehicleNetworkListener> listener(mListener.get()); mVN = VehicleNetwork::createVehicleNetwork(listener); ASSERT_TRUE(mVN.get() != NULL); mHalMock = new VehicleHalMockForAudioFocus(mVN); sp<VehicleHalMock> halMock = mHalMock; mVN->startMocking(halMock); mAudioHelper = new VehicleNetworkAudioHelper(); ASSERT_EQ(NO_ERROR, mAudioHelper->init()); } virtual void TearDown() { mAudioHelper->release(); sp<VehicleHalMock> halMock = mHalMock; mVN->stopMocking(halMock); } void changeFocusState(int32_t state, int32_t streams, int32_t extState) { mHalMock->setFocusState(state, streams, extState); mVN->injectEvent(mHalMock->getCurrentFocus()); } protected: sp<VehicleHalMockForAudioFocus> mHalMock; sp<VehicleNetwork> mVN; sp<VehicleNetworkTestListener> mListener; sp<VehicleNetworkAudioHelper> mAudioHelper; }; TEST_F(VehicleNetworkAudioHelperTest, streamStartStop) { ASSERT_EQ(NO_ERROR, mVN->subscribe(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, 0)); int initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE); mAudioHelper->notifyStreamStarted(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0); ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount, WAIT_NS)); const vehicle_prop_value& lastValue = mListener->getLastValue(); ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STARTED, lastValue.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]); ASSERT_EQ(0, lastValue.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]); initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE); mAudioHelper->notifyStreamStarted(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1); ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount, WAIT_NS)); const vehicle_prop_value& lastValue1 = mListener->getLastValue(); ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STARTED, lastValue1.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]); ASSERT_EQ(1, lastValue1.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]); initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE); mAudioHelper->notifyStreamStopped(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0); ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount, WAIT_NS)); const vehicle_prop_value& lastValue2 = mListener->getLastValue(); ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STOPPED, lastValue2.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]); ASSERT_EQ(0, lastValue2.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]); } TEST_F(VehicleNetworkAudioHelperTest, testFocus) { ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0)); ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1)); mHalMock->setFocusState(VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, 0x1, 0); // should wait for event first. Otherwise polling will fail as change is not delivered yet. ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0, WAIT_NS)); ASSERT_FALSE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1, WAIT_NS)); ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0)); ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1)); mHalMock->setFocusState(VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, 0x3, 0); ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0, WAIT_NS)); ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1, WAIT_NS)); ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0)); ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS, mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1)); } }; // namespace android