1 /*
2  * Copyright (C) 2019 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 #define LOG_TAG "AudioPolicy_Boot_Test"
18 
19 #include <string>
20 #include <unordered_set>
21 
22 #include <gtest/gtest.h>
23 
24 #include <media/AudioSystem.h>
25 #include <media/TypeConverter.h>
26 #include <system/audio.h>
27 #include <utils/Log.h>
28 
29 #include "AudioPolicyManagerTestClient.h"
30 #include "AudioPolicyTestManager.h"
31 
32 using namespace android;
33 
TEST(AudioHealthTest,AttachedDeviceFound)34 TEST(AudioHealthTest, AttachedDeviceFound) {
35     unsigned int numPorts;
36     unsigned int generation1;
37     unsigned int generation;
38     struct audio_port_v7 *audioPorts = nullptr;
39     int attempts = 10;
40     do {
41         if (attempts-- < 0) {
42             free(audioPorts);
43             GTEST_FAIL() << "Query audio ports time out";
44         }
45         numPorts = 0;
46         ASSERT_EQ(NO_ERROR, AudioSystem::listAudioPorts(
47                 AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1));
48         if (numPorts == 0) {
49             free(audioPorts);
50             GTEST_FAIL() << "Number of audio ports should not be zero";
51         }
52 
53         audioPorts = (struct audio_port_v7 *)realloc(
54                 audioPorts, numPorts * sizeof(struct audio_port_v7));
55         status_t status = AudioSystem::listAudioPorts(
56                 AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_DEVICE, &numPorts, audioPorts, &generation);
57         if (status != NO_ERROR) {
58             free(audioPorts);
59             GTEST_FAIL() << "Query audio ports failed";
60         }
61     } while (generation1 != generation);
62     std::unordered_set<audio_devices_t> attachedDevices;
63     for (int i = 0 ; i < numPorts; i++) {
64         attachedDevices.insert(audioPorts[i].ext.device.type);
65     }
66     free(audioPorts);
67 
68     AudioPolicyManagerTestClient client;
69     AudioPolicyTestManager manager(&client);
70     manager.loadConfig();
71     ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
72 
73     for (auto desc : manager.getConfig().getInputDevices()) {
74         if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
75             std::string deviceType;
76             (void)DeviceConverter::toString(desc->type(), deviceType);
77             ADD_FAILURE() << "Input device \"" << deviceType << "\" not found";
78         }
79     }
80     for (auto desc : manager.getConfig().getOutputDevices()) {
81         if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
82             std::string deviceType;
83             (void)DeviceConverter::toString(desc->type(), deviceType);
84             ADD_FAILURE() << "Output device \"" << deviceType << "\" not found";
85         }
86     }
87 }
88 
TEST(AudioHealthTest,ConnectSupportedDevice)89 TEST(AudioHealthTest, ConnectSupportedDevice) {
90     AudioPolicyManagerTestClient client;
91     AudioPolicyTestManager manager(&client);
92     manager.loadConfig();
93     ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
94 
95     DeviceVector devices;
96     for (const auto& hwModule : manager.getConfig().getHwModules()) {
97         for (const auto& profile : hwModule->getOutputProfiles()) {
98             devices.merge(profile->getSupportedDevices());
99         }
100         for (const auto& profile : hwModule->getInputProfiles()) {
101             devices.merge(profile->getSupportedDevices());
102         }
103     }
104     for (const auto& device : devices) {
105         if (!audio_is_bluetooth_out_sco_device(device->type()) &&
106             !audio_is_bluetooth_in_sco_device(device->type())) {
107             // There are two reasons to only test connecting BT devices.
108             // 1) It is easier to construct a fake address.
109             // 2) This test will be run in presubmit. In that case, it makes sense to make the test
110             //    processing time short.
111             continue;
112         }
113         std::string address = "11:22:33:44:55:66";
114         ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
115                 AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
116         ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
117                 device->type(), AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(),
118                 "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
119         ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
120                 AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
121         ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
122                 device->type(), AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(),
123                 "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
124         ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
125                 AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
126     }
127 }
128