blob: 2eaaf5d99fa7648b323fc603951d5949d0659fd3 [file] [log] [blame]
Shunkai Yaodca65ce2022-12-02 05:35:41 +00001/*
2 * Copyright (C) 2022 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 "DevicesFactoryHalAidl"
18//#define LOG_NDEBUG 0
19
Shunkai Yao51202502022-12-12 06:11:46 +000020#include <aidl/android/hardware/audio/core/IModule.h>
Shunkai Yaodca65ce2022-12-02 05:35:41 +000021#include <android/binder_manager.h>
Mikhail Naganovfab697c2023-01-11 19:33:13 +000022#include <binder/IServiceManager.h>
Shunkai Yao51202502022-12-12 06:11:46 +000023#include <memory>
Shunkai Yaodca65ce2022-12-02 05:35:41 +000024#include <utils/Log.h>
25
Shunkai Yao51202502022-12-12 06:11:46 +000026#include "DeviceHalAidl.h"
Shunkai Yaodca65ce2022-12-02 05:35:41 +000027#include "DevicesFactoryHalAidl.h"
28
Shunkai Yao51202502022-12-12 06:11:46 +000029using namespace ::aidl::android::hardware::audio::core;
Shunkai Yaodca65ce2022-12-02 05:35:41 +000030using ::android::detail::AudioHalVersionInfo;
31
32namespace android {
33
Shunkai Yao51202502022-12-12 06:11:46 +000034DevicesFactoryHalAidl::DevicesFactoryHalAidl(std::shared_ptr<IConfig> iconfig)
35 : mIConfig(std::move(iconfig)) {
Shunkai Yaodca65ce2022-12-02 05:35:41 +000036 ALOG_ASSERT(iconfig != nullptr, "Provided default IConfig service is NULL");
Shunkai Yaodca65ce2022-12-02 05:35:41 +000037}
38
Shunkai Yaodca65ce2022-12-02 05:35:41 +000039// Opens a device with the specified name. To close the device, it is
40// necessary to release references to the returned object.
41status_t DevicesFactoryHalAidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
42 if (name == nullptr || device == nullptr) {
43 return BAD_VALUE;
44 }
Shunkai Yao51202502022-12-12 06:11:46 +000045
Mikhail Naganov31d46652023-01-10 18:29:25 +000046 std::shared_ptr<IModule> service;
47 // FIXME: Normally we will list available HAL modules and connect to them,
48 // however currently we still get the list of module names from the config.
49 // Since the example service does not have all modules, the SM will wait
50 // for the missing ones forever.
jiabinfb55dc12023-03-16 22:52:30 +000051 if (strcmp(name, "primary") == 0 || strcmp(name, "r_submix") == 0 || strcmp(name, "usb") == 0) {
Mikhail Naganov31d46652023-01-10 18:29:25 +000052 if (strcmp(name, "primary") == 0) name = "default";
53 auto serviceName = std::string(IModule::descriptor) + "/" + name;
54 service = IModule::fromBinder(
Shunkai Yao51202502022-12-12 06:11:46 +000055 ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
Mikhail Naganov31d46652023-01-10 18:29:25 +000056 ALOGE_IF(service == nullptr, "%s fromBinder %s failed", __func__, serviceName.c_str());
Shunkai Yao51202502022-12-12 06:11:46 +000057 }
Mikhail Naganov31d46652023-01-10 18:29:25 +000058 // If the service is a nullptr, the device will not be really functional,
59 // but will not crash either.
Mikhail Naganov5b1eed12023-01-25 11:29:11 -080060 *device = sp<DeviceHalAidl>::make(name, service);
Shunkai Yao51202502022-12-12 06:11:46 +000061 return OK;
Shunkai Yaodca65ce2022-12-02 05:35:41 +000062}
63
64status_t DevicesFactoryHalAidl::getHalPids(std::vector<pid_t> *pids) {
65 if (pids == nullptr) {
66 return BAD_VALUE;
67 }
Mikhail Naganovfab697c2023-01-11 19:33:13 +000068 // The functionality for retrieving debug infos of services is not exposed via the NDK.
69 sp<IServiceManager> sm = defaultServiceManager();
70 if (sm == nullptr) {
71 return NO_INIT;
72 }
73 std::set<pid_t> pidsSet;
74 const auto moduleServiceName = std::string(IModule::descriptor) + "/";
75 auto debugInfos = sm->getServiceDebugInfo();
76 for (const auto& info : debugInfos) {
77 if (info.pid > 0 &&
78 info.name.size() > moduleServiceName.size() && // '>' as there must be instance name
79 info.name.substr(0, moduleServiceName.size()) == moduleServiceName) {
80 pidsSet.insert(info.pid);
81 }
82 }
83 *pids = {pidsSet.begin(), pidsSet.end()};
84 return NO_ERROR;
Shunkai Yaodca65ce2022-12-02 05:35:41 +000085}
86
87status_t DevicesFactoryHalAidl::setCallbackOnce(sp<DevicesFactoryHalCallback> callback) {
Mikhail Naganov31d46652023-01-10 18:29:25 +000088 // Dynamic registration of module instances is not supported. The functionality
89 // in the audio server which is related to this callback can be removed together
90 // with HIDL support.
91 ALOG_ASSERT(callback != nullptr);
92 if (callback != nullptr) {
93 callback->onNewDevicesAvailable();
Shunkai Yaodca65ce2022-12-02 05:35:41 +000094 }
Mikhail Naganov31d46652023-01-10 18:29:25 +000095 return NO_ERROR;
Shunkai Yaodca65ce2022-12-02 05:35:41 +000096}
97
98AudioHalVersionInfo DevicesFactoryHalAidl::getHalVersion() const {
99 int32_t versionNumber = 0;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000100 if (mIConfig != 0) {
101 if (ndk::ScopedAStatus status = mIConfig->getInterfaceVersion(&versionNumber);
102 !status.isOk()) {
103 ALOGE("%s getInterfaceVersion failed: %s", __func__, status.getDescription().c_str());
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000104 }
Mikhail Naganov31d46652023-01-10 18:29:25 +0000105 } else {
106 ALOGW("%s no IConfig instance", __func__);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000107 }
108 // AIDL does not have minor version, fill 0 for all versions
109 return AudioHalVersionInfo(AudioHalVersionInfo::Type::AIDL, versionNumber);
110}
111
112// Main entry-point to the shared library.
113extern "C" __attribute__((visibility("default"))) void* createIDevicesFactoryImpl() {
Shunkai Yao51202502022-12-12 06:11:46 +0000114 auto serviceName = std::string(IConfig::descriptor) + "/default";
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000115 auto service = IConfig::fromBinder(
Shunkai Yao51202502022-12-12 06:11:46 +0000116 ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
117 if (!service) {
118 ALOGE("%s binder service %s not exist", __func__, serviceName.c_str());
119 return nullptr;
120 }
121 return new DevicesFactoryHalAidl(service);
Shunkai Yaodca65ce2022-12-02 05:35:41 +0000122}
123
124} // namespace android