1 /*
2 * Copyright 2021 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 #include "hal_version_manager.h"
18
19 #include <android/binder_manager.h>
20 #include <android/hidl/manager/1.2/IServiceManager.h>
21 #include <bluetooth/log.h>
22 #include <hidl/ServiceManagement.h>
23
24 #include <memory>
25
26 #include "aidl/audio_aidl_interfaces.h"
27 #include "os/log.h"
28
29 namespace bluetooth {
30 namespace audio {
31
32 using ::aidl::android::hardware::bluetooth::audio::
33 IBluetoothAudioProviderFactory;
34
35 static const std::string kDefaultAudioProviderFactoryInterface =
36 std::string() + IBluetoothAudioProviderFactory::descriptor + "/default";
37
toString(BluetoothAudioHalTransport transport)38 std::string toString(BluetoothAudioHalTransport transport) {
39 switch (transport) {
40 case BluetoothAudioHalTransport::UNKNOWN:
41 return "UNKNOWN";
42 case BluetoothAudioHalTransport::HIDL:
43 return "HIDL";
44 case BluetoothAudioHalTransport::AIDL:
45 return "AIDL";
46 default:
47 return std::to_string(static_cast<int32_t>(transport));
48 }
49 }
50
51 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_UNAVAILABLE =
52 BluetoothAudioHalVersion();
53 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_0 =
54 BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0);
55 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_1 =
56 BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1);
57 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V1 =
58 BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0);
59 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V2 =
60 BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0);
61 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V3 =
62 BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0);
63 const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V4 =
64 BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0);
65
66 // Ideally HalVersionManager can be a singleton class
67 std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr =
68 std::make_unique<HalVersionManager>();
69
70 /**
71 * A singleton implementation to get the AIDL interface version.
72 */
GetAidlInterfaceVersion()73 BluetoothAudioHalVersion GetAidlInterfaceVersion() {
74 static auto aidl_version = []() -> BluetoothAudioHalVersion {
75 int version = 0;
76 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
77 ::ndk::SpAIBinder(AServiceManager_waitForService(
78 kDefaultAudioProviderFactoryInterface.c_str())));
79
80 if (provider_factory == nullptr) {
81 log::error(
82 "getInterfaceVersion: Can't get aidl version from unknown factory");
83 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
84 }
85
86 auto aidl_retval = provider_factory->getInterfaceVersion(&version);
87 if (!aidl_retval.isOk()) {
88 log::error("BluetoothAudioHal::getInterfaceVersion failure: {}",
89 aidl_retval.getDescription());
90 return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
91 }
92
93 return BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, version,
94 0);
95 }();
96
97 return aidl_version;
98 }
99
GetHalTransport()100 BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
101 return instance_ptr->hal_version_.getTransport();
102 }
103
GetHalVersion()104 BluetoothAudioHalVersion HalVersionManager::GetHalVersion() {
105 std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
106 return instance_ptr->hal_version_;
107 }
108
109 android::sp<IBluetoothAudioProvidersFactory_2_1>
GetProvidersFactory_2_1()110 HalVersionManager::GetProvidersFactory_2_1() {
111 std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
112 if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_1) {
113 return nullptr;
114 }
115 android::sp<IBluetoothAudioProvidersFactory_2_1> providers_factory =
116 IBluetoothAudioProvidersFactory_2_1::getService();
117 log::assert_that(
118 providers_factory != nullptr,
119 "V2_1::IBluetoothAudioProvidersFactory::getService() failed");
120
121 log::info("V2_1::IBluetoothAudioProvidersFactory::getService() returned {}{}",
122 fmt::ptr(providers_factory.get()),
123 (providers_factory->isRemote() ? " (remote)" : " (local)"));
124 return providers_factory;
125 }
126
127 android::sp<IBluetoothAudioProvidersFactory_2_0>
GetProvidersFactory_2_0()128 HalVersionManager::GetProvidersFactory_2_0() {
129 std::unique_lock<std::mutex> guard(instance_ptr->mutex_);
130 if (instance_ptr->hal_version_ == BluetoothAudioHalVersion::VERSION_2_1) {
131 guard.unlock();
132 return instance_ptr->GetProvidersFactory_2_1();
133 }
134 android::sp<IBluetoothAudioProvidersFactory_2_0> providers_factory =
135 IBluetoothAudioProvidersFactory_2_0::getService();
136 log::assert_that(
137 providers_factory != nullptr,
138 "V2_0::IBluetoothAudioProvidersFactory::getService() failed");
139
140 log::info("V2_0::IBluetoothAudioProvidersFactory::getService() returned {}{}",
141 fmt::ptr(providers_factory.get()),
142 (providers_factory->isRemote() ? " (remote)" : " (local)"));
143 guard.unlock();
144 return providers_factory;
145 }
146
HalVersionManager()147 HalVersionManager::HalVersionManager() {
148 hal_transport_ = BluetoothAudioHalTransport::UNKNOWN;
149 if (AServiceManager_checkService(
150 kDefaultAudioProviderFactoryInterface.c_str()) != nullptr) {
151 hal_version_ = GetAidlInterfaceVersion();
152 hal_transport_ = BluetoothAudioHalTransport::AIDL;
153 return;
154 }
155
156 auto service_manager = android::hardware::defaultServiceManager1_2();
157 log::assert_that(service_manager != nullptr,
158 "assert failed: service_manager != nullptr");
159 size_t instance_count = 0;
160 auto listManifestByInterface_cb =
161 [&instance_count](
162 const hidl_vec<android::hardware::hidl_string>& instanceNames) {
163 instance_count = instanceNames.size();
164 };
165 auto hidl_retval = service_manager->listManifestByInterface(
166 kFullyQualifiedInterfaceName_2_1, listManifestByInterface_cb);
167 if (!hidl_retval.isOk()) {
168 log::fatal("IServiceManager::listByInterface failure: {}",
169 hidl_retval.description());
170 return;
171 }
172
173 if (instance_count > 0) {
174 hal_version_ = BluetoothAudioHalVersion::VERSION_2_1;
175 hal_transport_ = BluetoothAudioHalTransport::HIDL;
176 return;
177 }
178
179 hidl_retval = service_manager->listManifestByInterface(
180 kFullyQualifiedInterfaceName_2_0, listManifestByInterface_cb);
181 if (!hidl_retval.isOk()) {
182 log::fatal("IServiceManager::listByInterface failure: {}",
183 hidl_retval.description());
184 return;
185 }
186
187 if (instance_count > 0) {
188 hal_version_ = BluetoothAudioHalVersion::VERSION_2_0;
189 hal_transport_ = BluetoothAudioHalTransport::HIDL;
190 return;
191 }
192
193 hal_version_ = BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
194 log::error("No supported HAL version");
195 }
196
197 } // namespace audio
198 } // namespace bluetooth
199