1 /*
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 #pragma once
18
19 #include <binder/Common.h>
20 #include <binder/IBinder.h>
21
22 #if !defined(__BIONIC__) && defined(BINDER_ENABLE_LIBLOG_ASSERT)
23 #include <log/log.h>
24 #define __assert(file, line, message) LOG_ALWAYS_FATAL(file ":" #line ": " message)
25 #endif
26
27 #ifndef __BIONIC__
28 #ifndef __assert
29
30 // defined differently by liblog
31 #pragma push_macro("LOG_PRI")
32 #ifdef LOG_PRI
33 #undef LOG_PRI
34 #endif
35 #include <syslog.h>
36 #pragma pop_macro("LOG_PRI")
37
38 #define __assert(a, b, c) \
39 do { \
40 syslog(LOG_ERR, a ": " c); \
41 abort(); \
42 } while (false)
43 #endif // __assert
44 #endif // __BIONIC__
45
46 namespace android {
47
48 /*
49 * Used to manage AIDL's *Delegator types.
50 * This is used to:
51 * - create a new *Delegator object that delegates to the binder argument.
52 * - or return an existing *Delegator object that already delegates to the
53 * binder argument.
54 * - or return the underlying delegate binder if the binder argument is a
55 * *Delegator itself.
56 *
57 * @param binder - the binder to delegate to or unwrap
58 *
59 * @return pointer to the *Delegator object or the unwrapped binder object
60 */
61 template <typename T>
delegate(const sp<T> & binder)62 sp<T> delegate(const sp<T>& binder) {
63 const void* isDelegatorId = &T::descriptor;
64 const void* hasDelegatorId = &T::descriptor + 1;
65 // is binder itself a delegator?
66 if (T::asBinder(binder)->findObject(isDelegatorId)) {
67 if (T::asBinder(binder)->findObject(hasDelegatorId)) {
68 __assert(__FILE__, __LINE__,
69 "This binder has a delegator and is also delegator itself! This is "
70 "likely an unintended mixing of binders.");
71 return nullptr;
72 }
73 // unwrap the delegator
74 return static_cast<typename T::DefaultDelegator*>(binder.get())->getImpl();
75 }
76
77 struct MakeArgs {
78 const sp<T>* binder;
79 const void* id;
80 } makeArgs;
81 makeArgs.binder = &binder;
82 makeArgs.id = isDelegatorId;
83
84 // the binder is not a delegator, so construct one
85 sp<IBinder> newDelegator = T::asBinder(binder)->lookupOrCreateWeak(
86 hasDelegatorId,
87 [](const void* args) -> sp<IBinder> {
88 auto delegator = sp<typename T::DefaultDelegator>::make(
89 *static_cast<const MakeArgs*>(args)->binder);
90 // make sure we know this binder is a delegator by attaching a unique ID
91 (void)delegator->attachObject(static_cast<const MakeArgs*>(args)->id,
92 reinterpret_cast<void*>(0x1), nullptr, nullptr);
93 return delegator;
94 },
95 static_cast<const void*>(&makeArgs));
96 return sp<typename T::DefaultDelegator>::cast(newDelegator);
97 }
98
99 } // namespace android
100