xref: /aosp_15_r20/system/libhidl/transport/HidlPassthroughSupport.cpp (revision 8222fbe171c3d6fadfe95119c180cf3010c392a8)
1*8222fbe1SAndroid Build Coastguard Worker /*
2*8222fbe1SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*8222fbe1SAndroid Build Coastguard Worker  *
4*8222fbe1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8222fbe1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8222fbe1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8222fbe1SAndroid Build Coastguard Worker  *
8*8222fbe1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8222fbe1SAndroid Build Coastguard Worker  *
10*8222fbe1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8222fbe1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8222fbe1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8222fbe1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8222fbe1SAndroid Build Coastguard Worker  * limitations under the License.
15*8222fbe1SAndroid Build Coastguard Worker  */
16*8222fbe1SAndroid Build Coastguard Worker 
17*8222fbe1SAndroid Build Coastguard Worker #include <hidl/HidlPassthroughSupport.h>
18*8222fbe1SAndroid Build Coastguard Worker 
19*8222fbe1SAndroid Build Coastguard Worker #include "InternalStatic.h"  // TODO(b/69122224): remove this include, for tryWrap
20*8222fbe1SAndroid Build Coastguard Worker 
21*8222fbe1SAndroid Build Coastguard Worker #include <hidl/HidlTransportUtils.h>
22*8222fbe1SAndroid Build Coastguard Worker #include <hidl/Static.h>
23*8222fbe1SAndroid Build Coastguard Worker 
24*8222fbe1SAndroid Build Coastguard Worker using ::android::hidl::base::V1_0::IBase;
25*8222fbe1SAndroid Build Coastguard Worker 
26*8222fbe1SAndroid Build Coastguard Worker namespace android {
27*8222fbe1SAndroid Build Coastguard Worker namespace hardware {
28*8222fbe1SAndroid Build Coastguard Worker namespace details {
29*8222fbe1SAndroid Build Coastguard Worker 
tryWrap(const std::string & descriptor,sp<IBase> iface)30*8222fbe1SAndroid Build Coastguard Worker static sp<IBase> tryWrap(const std::string& descriptor, sp<IBase> iface) {
31*8222fbe1SAndroid Build Coastguard Worker     auto func = getBsConstructorMap().get(descriptor, nullptr);
32*8222fbe1SAndroid Build Coastguard Worker     if (func) {
33*8222fbe1SAndroid Build Coastguard Worker         return func(static_cast<void*>(iface.get()));
34*8222fbe1SAndroid Build Coastguard Worker     }
35*8222fbe1SAndroid Build Coastguard Worker     return nullptr;
36*8222fbe1SAndroid Build Coastguard Worker }
37*8222fbe1SAndroid Build Coastguard Worker 
wrapPassthroughInternal(sp<IBase> iface)38*8222fbe1SAndroid Build Coastguard Worker sp<IBase> wrapPassthroughInternal(sp<IBase> iface) {
39*8222fbe1SAndroid Build Coastguard Worker     if (iface == nullptr || iface->isRemote()) {
40*8222fbe1SAndroid Build Coastguard Worker         // doesn't know how to handle it.
41*8222fbe1SAndroid Build Coastguard Worker         return iface;
42*8222fbe1SAndroid Build Coastguard Worker     }
43*8222fbe1SAndroid Build Coastguard Worker 
44*8222fbe1SAndroid Build Coastguard Worker     // Consider the case when an AOSP interface is extended by partners.
45*8222fbe1SAndroid Build Coastguard Worker     // Then the partner's HAL interface library is loaded only in the vndk
46*8222fbe1SAndroid Build Coastguard Worker     // linker namespace, but not in the default linker namespace, where
47*8222fbe1SAndroid Build Coastguard Worker     // this code runs. As a result, BsConstructorMap in the latter does not
48*8222fbe1SAndroid Build Coastguard Worker     // have the entry for the descriptor name.
49*8222fbe1SAndroid Build Coastguard Worker     //
50*8222fbe1SAndroid Build Coastguard Worker     // Therefore, we try to wrap using the descript names of the parent
51*8222fbe1SAndroid Build Coastguard Worker     // types along the interface chain, instead of always using the descriptor
52*8222fbe1SAndroid Build Coastguard Worker     // name of the current interface.
53*8222fbe1SAndroid Build Coastguard Worker     sp<IBase> base;
54*8222fbe1SAndroid Build Coastguard Worker     auto ret = iface->interfaceChain([&](const auto& types) {
55*8222fbe1SAndroid Build Coastguard Worker         for (const std::string& descriptor : types) {
56*8222fbe1SAndroid Build Coastguard Worker             base = tryWrap(descriptor, iface);
57*8222fbe1SAndroid Build Coastguard Worker             if (base != nullptr) {
58*8222fbe1SAndroid Build Coastguard Worker                 break;  // wrap is successful. no need to lookup further.
59*8222fbe1SAndroid Build Coastguard Worker             }
60*8222fbe1SAndroid Build Coastguard Worker         }
61*8222fbe1SAndroid Build Coastguard Worker     });
62*8222fbe1SAndroid Build Coastguard Worker 
63*8222fbe1SAndroid Build Coastguard Worker     if (!ret.isOk()) {
64*8222fbe1SAndroid Build Coastguard Worker         return nullptr;
65*8222fbe1SAndroid Build Coastguard Worker     }
66*8222fbe1SAndroid Build Coastguard Worker 
67*8222fbe1SAndroid Build Coastguard Worker     // It is ensured that if this function is called with an instance of IType
68*8222fbe1SAndroid Build Coastguard Worker     // then the corresponding descriptor would be in the BsConstructorMap.
69*8222fbe1SAndroid Build Coastguard Worker     // This is because referencing IType implies that the interface library
70*8222fbe1SAndroid Build Coastguard Worker     // defining the type has already been loaded into the current linker
71*8222fbe1SAndroid Build Coastguard Worker     // namespace, and thus the library should have added an entry into the
72*8222fbe1SAndroid Build Coastguard Worker     // BsConstructorMap while executing the library's constructor.
73*8222fbe1SAndroid Build Coastguard Worker     return base;
74*8222fbe1SAndroid Build Coastguard Worker }
75*8222fbe1SAndroid Build Coastguard Worker 
76*8222fbe1SAndroid Build Coastguard Worker }  // namespace details
77*8222fbe1SAndroid Build Coastguard Worker }  // namespace hardware
78*8222fbe1SAndroid Build Coastguard Worker }  // namespace android
79