1 /*
2 * Copyright (C) 2020 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 #ifndef ANDROID_AUDIO_CONFIG_H
18 #define ANDROID_AUDIO_CONFIG_H
19
20 #ifdef __cplusplus
21
22 #include <string>
23 #include <unistd.h>
24 #include <vector>
25
26 #include <cutils/properties.h>
27
28 namespace android {
29
30 // Returns a vector of paths where audio configuration files
31 // must be searched, in the provided order.
audio_get_configuration_paths()32 static inline std::vector<std::string> audio_get_configuration_paths() {
33 static const std::vector<std::string> paths = []() {
34 char value[PROPERTY_VALUE_MAX] = {};
35 if (property_get("ro.boot.product.vendor.sku", value, "") <= 0) {
36 return std::vector<std::string>({"/odm/etc", "/vendor/etc", "/system/etc"});
37 } else {
38 return std::vector<std::string>({
39 "/odm/etc", std::string("/vendor/etc/audio/sku_") + value,
40 "/vendor/etc", "/system/etc"});
41 }
42 }();
43 return paths;
44 }
45
audio_find_readable_configuration_file(const char * fileName)46 static inline std::string audio_find_readable_configuration_file(const char* fileName) {
47 for (const auto& path : audio_get_configuration_paths()) {
48 std::string tryPath = path + "/" + fileName;
49 if (access(tryPath.c_str(), R_OK) == 0) {
50 return tryPath;
51 }
52 }
53 return {};
54 }
55
audio_get_audio_policy_config_file()56 static inline std::string audio_get_audio_policy_config_file() {
57 static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
58 static constexpr const char *apmA2dpOffloadDisabledXmlConfigFileName =
59 "audio_policy_configuration_a2dp_offload_disabled.xml";
60 static constexpr const char *apmBluetoothLegacyHalXmlConfigFileName =
61 "audio_policy_configuration_bluetooth_legacy_hal.xml";
62
63 std::string audioPolicyXmlConfigFile;
64 // First try alternative files if needed
65 if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false)) {
66 if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false) &&
67 property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
68 // Both BluetoothAudio@2.0 and BluetoothA2dp@1.0 (Offload) are disabled, and uses
69 // the legacy hardware module for A2DP and hearing aid.
70 audioPolicyXmlConfigFile = audio_find_readable_configuration_file(
71 apmBluetoothLegacyHalXmlConfigFileName);
72 } else if (property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
73 // A2DP offload supported but disabled: try to use special XML file
74 audioPolicyXmlConfigFile = audio_find_readable_configuration_file(
75 apmA2dpOffloadDisabledXmlConfigFileName);
76 }
77 } else if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false)) {
78 audioPolicyXmlConfigFile = audio_find_readable_configuration_file(
79 apmBluetoothLegacyHalXmlConfigFileName);
80 }
81 return audioPolicyXmlConfigFile.empty() ?
82 audio_find_readable_configuration_file(apmXmlConfigFileName) : audioPolicyXmlConfigFile;
83 }
84
85 } // namespace android
86
87 #endif // __cplusplus
88
89 #endif // ANDROID_AUDIO_CONFIG_H
90