/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "hidl-utils.h" #include #include #include #include #include #include #include #include #include #include #include namespace android::hardware::radio::service { using namespace std::string_literals; static std::vector> gPublishedHals; template static void publishRadioHal(std::shared_ptr ctx, sp hidlHal, std::shared_ptr cm, const std::string& slot) { const auto instance = T::descriptor + "/"s + slot; if (!AServiceManager_isDeclared(instance.c_str())) { LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)"; return; } LOG(DEBUG) << "Publishing " << instance; auto aidlHal = ndk::SharedRefBase::make(ctx, hidlHal, cm); gPublishedHals.push_back(aidlHal); const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str()); CHECK_EQ(status, STATUS_OK); } static void publishRadio(std::string slot) { auto radioHidl = V1_5::IRadio::getService(slot); CHECK(radioHidl) << "HIDL IRadio not present in VINTF"; hidl_utils::linkDeathToDeath(radioHidl); auto context = std::make_shared(); auto callbackMgr = std::make_shared(context, radioHidl); publishRadioHal(context, radioHidl, callbackMgr, slot); publishRadioHal(context, radioHidl, callbackMgr, slot); publishRadioHal(context, radioHidl, callbackMgr, slot); publishRadioHal(context, radioHidl, callbackMgr, slot); publishRadioHal(context, radioHidl, callbackMgr, slot); publishRadioHal(context, radioHidl, callbackMgr, slot); } static void publishRadioConfig() { auto hidlHal = config::V1_1::IRadioConfig::getService(); CHECK(hidlHal) << "HIDL IRadioConfig not present in VINTF"; hidl_utils::linkDeathToDeath(hidlHal); auto aidlHal = ndk::SharedRefBase::make(hidlHal); gPublishedHals.push_back(aidlHal); const auto instance = compat::RadioConfig::descriptor + "/default"s; const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str()); CHECK_EQ(status, STATUS_OK); } static void main() { base::InitLogging(nullptr, base::LogdLogger(base::RADIO)); base::SetDefaultTag("radiocompat"); base::SetMinimumLogSeverity(base::VERBOSE); LOG(DEBUG) << "Radio HAL compat service starting..."; publishRadioConfig(); const auto slots = hidl_utils::listManifestByInterface(V1_0::IRadio::descriptor); LOG(INFO) << "Found " << slots.size() << " slot(s)"; for (const auto& slot : slots) { publishRadio(slot); } LOG(DEBUG) << "Radio HAL compat service is operational"; ABinderProcess_joinThreadPool(); LOG(FATAL) << "Radio HAL compat service has stopped"; } } // namespace android::hardware::radio::service int main() { android::hardware::radio::service::main(); return EXIT_FAILURE; // should not reach }