10b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland/*
20b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * Copyright (C) 2017 The Android Open Source Project
30b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland *
40b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * Licensed under the Apache License, Version 2.0 (the "License");
50b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * you may not use this file except in compliance with the License.
60b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * You may obtain a copy of the License at
70b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland *
80b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland *      http://www.apache.org/licenses/LICENSE-2.0
90b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland *
100b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * Unless required by applicable law or agreed to in writing, software
110b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * distributed under the License is distributed on an "AS IS" BASIS,
120b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * See the License for the specific language governing permissions and
140b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland * limitations under the License.
150b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland */
160b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
170b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland#include <hidl/HidlPassthroughSupport.h>
180b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
190b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland#include <hidl/HidlTransportUtils.h>
200b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland#include <hidl/Static.h>
210b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
220b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Morelandusing ::android::hidl::base::V1_0::IBase;
230b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
240b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Morelandnamespace android {
250b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Morelandnamespace hardware {
260b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Morelandnamespace details {
270b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
288ca9bd6f42be723d0aa212c260ee797061239939Jiyong Parkstatic sp<IBase> tryWrap(const std::string& descriptor, sp<IBase> iface) {
298ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    auto func = getBsConstructorMap().get(descriptor, nullptr);
306538e7515b00694574b222da2898716e3cb1431aSteven Moreland    if (!func) {
316538e7515b00694574b222da2898716e3cb1431aSteven Moreland        func = gBsConstructorMap.get(descriptor, nullptr);
326538e7515b00694574b222da2898716e3cb1431aSteven Moreland    }
338ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    if (func) {
348ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park        return func(static_cast<void*>(iface.get()));
358ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    }
368ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    return nullptr;
378ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park}
388ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park
390b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Morelandsp<IBase> wrapPassthroughInternal(sp<IBase> iface) {
400b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland    if (iface == nullptr || iface->isRemote()) {
410b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland        // doesn't know how to handle it.
420b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland        return iface;
430b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland    }
448ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park
458ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // Consider the case when an AOSP interface is extended by partners.
468ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // Then the partner's HAL interface library is loaded only in the vndk
478ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // linker namespace, but not in the default linker namespace, where
488ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // this code runs. As a result, BsConstructorMap in the latter does not
498ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // have the entry for the descriptor name.
508ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    //
518ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // Therefore, we try to wrap using the descript names of the parent
528ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // types along the interface chain, instead of always using the descriptor
538ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // name of the current interface.
548ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    sp<IBase> base;
558ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    auto ret = iface->interfaceChain([&](const auto& types) {
568ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park        for (const std::string& descriptor : types) {
578ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park            base = tryWrap(descriptor, iface);
588ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park            if (base != nullptr) {
598ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park                break;  // wrap is successful. no need to lookup further.
608ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park            }
61c6ce6e50a77c08a17a28013599469b83d11049b0Yifan Hong        }
628ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    });
630b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
648ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    if (!ret.isOk()) {
658ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park        return nullptr;
668ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    }
670b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
688ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // It is ensured that if this function is called with an instance of IType
698ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // then the corresponding descriptor would be in the BsConstructorMap.
708ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // This is because referencing IType implies that the interface library
718ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // defining the type has already been loaded into the current linker
728ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // namespace, and thus the library should have added an entry into the
738ca9bd6f42be723d0aa212c260ee797061239939Jiyong Park    // BsConstructorMap while executing the library's constructor.
740b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland    return base;
750b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland}
760b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland
770b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland}  // namespace details
780b1e62a08d739ad031d745a7e0a4039b5f5023f9Steven Moreland}  // namespace hardware
7997f88f31b63c5f4cb12be40cbd9cc8d725a4ef80Yifan Hong}  // namespace android
80