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 #define LOG_TAG "VehicleNetworkAudioHelperTest"
17 
18 #include <unistd.h>
19 
20 #include <gtest/gtest.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/ProcessState.h>
23 #include <utils/threads.h>
24 #include <utils/KeyedVector.h>
25 #include <utils/String8.h>
26 #include <utils/SystemClock.h>
27 #include <vehicle-internal.h>
28 #include <VehicleNetwork.h>
29 #include <VehicleNetworkAudioHelper.h>
30 
31 #include "TestProperties.h"
32 #include "VehicleHalMock.h"
33 #include "VehicleNetworkTestListener.h"
34 
35 namespace android {
36 
37 extern "C" {
38 vehicle_prop_config_t const * getTestPropertiesForAudio();
39 int getNumTestPropertiesForAudio();
40 };
41 
42 class VehicleHalMockForAudioFocus : public VehicleHalMock {
43 public:
VehicleHalMockForAudioFocus(sp<VehicleNetwork> & vn)44     VehicleHalMockForAudioFocus(sp<VehicleNetwork>& vn)
45         : mVN(vn) {
46         mAudioProperties = new VehiclePropertiesHolder(false /* deleteConfigsInDestructor */);
47         vehicle_prop_config_t const * properties = getTestPropertiesForAudio();
48         for (int i = 0; i < getNumTestPropertiesForAudio(); i++) {
49             mAudioProperties->getList().push_back(properties + i);
50         }
51         mValueToGet.prop = VEHICLE_PROPERTY_AUDIO_FOCUS;
52         mValueToGet.value_type = VEHICLE_VALUE_TYPE_INT32_VEC4;
53         mValueToGet.value.int32_array[0] = 0;
54         mValueToGet.value.int32_array[1] = 0;
55         mValueToGet.value.int32_array[2] = 0;
56         mValueToGet.value.int32_array[3] = 0;
57     }
~VehicleHalMockForAudioFocus()58     virtual ~VehicleHalMockForAudioFocus() {};
59 
onListProperties()60     virtual sp<VehiclePropertiesHolder> onListProperties() {
61         ALOGI("onListProperties");
62         Mutex::Autolock autoLock(mLock);
63         return mAudioProperties;
64     };
65 
onPropertySet(const vehicle_prop_value_t & value)66     virtual status_t onPropertySet(const vehicle_prop_value_t& value) {
67         ALOGI("onPropertySet 0x%x", value.prop);
68         return NO_ERROR;
69     };
70 
onPropertyGet(vehicle_prop_value_t * value)71     virtual status_t onPropertyGet(vehicle_prop_value_t* value) {
72         ALOGI("onPropertyGet 0x%x", value->prop);
73         Mutex::Autolock autoLock(mLock);
74         if (value->prop == VEHICLE_PROPERTY_AUDIO_FOCUS) {
75             memcpy(value, &mValueToGet, sizeof(vehicle_prop_value_t));
76         }
77         return NO_ERROR;
78     };
79 
onPropertySubscribe(int32_t property,float,int32_t)80     virtual status_t onPropertySubscribe(int32_t property, float /*sampleRate*/,
81             int32_t /*zones*/) {
82         ALOGI("onPropertySubscribe 0x%x", property);
83         return NO_ERROR;
84     };
85 
onPropertyUnsubscribe(int32_t property)86     virtual void onPropertyUnsubscribe(int32_t property) {
87         ALOGI("onPropertySubscribe 0x%x", property);
88     };
89 
setFocusState(int32_t state,int32_t streams,int32_t extState)90     void setFocusState(int32_t state, int32_t streams, int32_t extState) {
91         Mutex::Autolock autoLock(mLock);
92         mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_FOCUS] = state;
93         mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_STREAMS] = streams;
94         mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_EXTERNAL_FOCUS_STATE] = extState;
95         mValueToGet.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_AUDIO_CONTEXTS] = 0;
96         mValueToGet.timestamp = elapsedRealtimeNano();
97         mVN->injectEvent(mValueToGet);
98     }
99 
getCurrentFocus()100     const vehicle_prop_value_t& getCurrentFocus() {
101         Mutex::Autolock autoLock(mLock);
102         return mValueToGet;
103     }
104 
105 private:
106     sp<VehicleNetwork> mVN;
107     mutable Mutex mLock;
108     sp<VehiclePropertiesHolder> mAudioProperties;
109     vehicle_prop_value_t mValueToGet;
110 };
111 
112 class VehicleNetworkAudioHelperTest : public testing::Test {
113 public:
VehicleNetworkAudioHelperTest()114     VehicleNetworkAudioHelperTest() :
115         mHalMock(NULL),
116         mVN(NULL),
117         mListener(new VehicleNetworkTestListener()) { }
118 
~VehicleNetworkAudioHelperTest()119     ~VehicleNetworkAudioHelperTest() {}
120 
121     const nsecs_t WAIT_NS = 100000000;
122 
123 protected:
SetUp()124     virtual void SetUp() {
125         ASSERT_TRUE(mListener.get() != NULL);
126         sp<VehicleNetworkListener> listener(mListener.get());
127         mVN = VehicleNetwork::createVehicleNetwork(listener);
128         ASSERT_TRUE(mVN.get() != NULL);
129         mHalMock = new VehicleHalMockForAudioFocus(mVN);
130         sp<VehicleHalMock> halMock = mHalMock;
131         mVN->startMocking(halMock);
132         mAudioHelper = new VehicleNetworkAudioHelper();
133         ASSERT_EQ(NO_ERROR, mAudioHelper->init());
134     }
135 
TearDown()136     virtual void TearDown() {
137         mAudioHelper->release();
138         sp<VehicleHalMock> halMock = mHalMock;
139         mVN->stopMocking(halMock);
140     }
141 
changeFocusState(int32_t state,int32_t streams,int32_t extState)142     void changeFocusState(int32_t state, int32_t streams, int32_t extState) {
143         mHalMock->setFocusState(state, streams, extState);
144         mVN->injectEvent(mHalMock->getCurrentFocus());
145     }
146 
147 protected:
148     sp<VehicleHalMockForAudioFocus> mHalMock;
149     sp<VehicleNetwork> mVN;
150     sp<VehicleNetworkTestListener> mListener;
151     sp<VehicleNetworkAudioHelper> mAudioHelper;
152 };
153 
TEST_F(VehicleNetworkAudioHelperTest,streamStartStop)154 TEST_F(VehicleNetworkAudioHelperTest, streamStartStop) {
155     ASSERT_EQ(NO_ERROR, mVN->subscribe(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, 0));
156     int initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE);
157     mAudioHelper->notifyStreamStarted(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0);
158     ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount,
159             WAIT_NS));
160     const vehicle_prop_value& lastValue = mListener->getLastValue();
161     ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STARTED,
162             lastValue.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]);
163     ASSERT_EQ(0, lastValue.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]);
164 
165     initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE);
166     mAudioHelper->notifyStreamStarted(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1);
167     ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount,
168             WAIT_NS));
169     const vehicle_prop_value& lastValue1 = mListener->getLastValue();
170     ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STARTED,
171             lastValue1.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]);
172     ASSERT_EQ(1, lastValue1.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]);
173 
174     initialCount = mListener->getEventCount(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE);
175     mAudioHelper->notifyStreamStopped(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0);
176     ASSERT_TRUE(mListener->waitForEvent(VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE, initialCount,
177             WAIT_NS));
178     const vehicle_prop_value& lastValue2 = mListener->getLastValue();
179     ASSERT_EQ(VEHICLE_AUDIO_STREAM_STATE_STOPPED,
180             lastValue2.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE]);
181     ASSERT_EQ(0, lastValue2.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM]);
182 }
183 
TEST_F(VehicleNetworkAudioHelperTest,testFocus)184 TEST_F(VehicleNetworkAudioHelperTest, testFocus) {
185     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS,
186             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0));
187     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS,
188             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1));
189     mHalMock->setFocusState(VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, 0x1, 0);
190     // should wait for event first. Otherwise polling will fail as change is not delivered yet.
191     ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0,
192             WAIT_NS));
193     ASSERT_FALSE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1,
194             WAIT_NS));
195     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS,
196             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0));
197     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS,
198             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1));
199     mHalMock->setFocusState(VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, 0x3, 0);
200     ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0,
201             WAIT_NS));
202     ASSERT_TRUE(mAudioHelper->waitForStreamFocus(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1,
203             WAIT_NS));
204     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS,
205             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_0));
206     ASSERT_EQ(VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS,
207             mAudioHelper->getStreamFocusState(VEHICLE_NETWORK_AUDIO_HELPER_STREAM_1));
208 }
209 
210 }; // namespace android
211