• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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