1 /*
2 * Copyright (C) 2018 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 /**
18 * @addtogroup NdkBinder
19 * @{
20 */
21
22 /**
23 * @file binder_interface_utils.h
24 * @brief This provides common C++ classes for common operations and as base classes for C++
25 * interfaces.
26 */
27
28 #pragma once
29
30 #include <android/binder_auto_utils.h>
31 #include <android/binder_ibinder.h>
32
33 #if __has_include(<android/binder_shell.h>)
34 #include <android/binder_shell.h>
35 #define HAS_BINDER_SHELL_COMMAND
36 #endif //_has_include
37
38 #include <assert.h>
39
40 #include <memory>
41 #include <mutex>
42
43 namespace ndk {
44
45 /**
46 * analog using std::shared_ptr for internally held refcount
47 *
48 * ref must be called at least one time during the lifetime of this object. The recommended way to
49 * construct this object is with SharedRefBase::make.
50 */
51 class SharedRefBase {
52 public:
SharedRefBase()53 SharedRefBase() {}
~SharedRefBase()54 virtual ~SharedRefBase() {
55 std::call_once(mFlagThis, [&]() {
56 __assert(__FILE__, __LINE__, "SharedRefBase: no ref created during lifetime");
57 });
58
59 if (ref() != nullptr) {
60 __assert(__FILE__, __LINE__,
61 "SharedRefBase: destructed but still able to lock weak_ptr. Is this object "
62 "double-owned?");
63 }
64 }
65
66 /**
67 * A shared_ptr must be held to this object when this is called. This must be called once during
68 * the lifetime of this object.
69 */
ref()70 std::shared_ptr<SharedRefBase> ref() {
71 std::shared_ptr<SharedRefBase> thiz = mThis.lock();
72
73 std::call_once(mFlagThis, [&]() { mThis = thiz = std::shared_ptr<SharedRefBase>(this); });
74
75 return thiz;
76 }
77
78 /**
79 * Convenience method for a ref (see above) which automatically casts to the desired child type.
80 */
81 template <typename CHILD>
ref()82 std::shared_ptr<CHILD> ref() {
83 return std::static_pointer_cast<CHILD>(ref());
84 }
85
86 /**
87 * Convenience method for making an object directly with a reference.
88 */
89 template <class T, class... Args>
make(Args &&...args)90 static std::shared_ptr<T> make(Args&&... args) {
91 #pragma clang diagnostic push
92 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
93 T* t = new T(std::forward<Args>(args)...);
94 #pragma clang diagnostic pop
95 // warning: Potential leak of memory pointed to by 't' [clang-analyzer-unix.Malloc]
96 return t->template ref<T>(); // NOLINT(clang-analyzer-unix.Malloc)
97 }
98
delete(void * p)99 static void operator delete(void* p) { std::free(p); }
100
101 // Once minSdkVersion is 30, we are guaranteed to be building with the
102 // Android 11 AIDL compiler which supports the SharedRefBase::make API.
103 //
104 // Use 'SharedRefBase::make<T>(...)' to make. SharedRefBase has implicit
105 // ownership. Making this operator private to avoid double-ownership.
106 #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__)
107 private:
108 #else
109 [[deprecated("Prefer SharedRefBase::make<T>(...) if possible.")]]
110 #endif
new(size_t s)111 static void* operator new(size_t s) { return std::malloc(s); }
112
113 private:
114 std::once_flag mFlagThis;
115 std::weak_ptr<SharedRefBase> mThis;
116 };
117
118 /**
119 * wrapper analog to IInterface
120 */
121 class ICInterface : public SharedRefBase {
122 public:
ICInterface()123 ICInterface() {}
~ICInterface()124 virtual ~ICInterface() {}
125
126 /**
127 * This either returns the single existing implementation or creates a new implementation.
128 */
129 virtual SpAIBinder asBinder() = 0;
130
131 /**
132 * Returns whether this interface is in a remote process. If it cannot be determined locally,
133 * this will be checked using AIBinder_isRemote.
134 */
135 virtual bool isRemote() = 0;
136
137 /**
138 * Dumps information about the interface. By default, dumps nothing.
139 */
140 virtual inline binder_status_t dump(int fd, const char** args, uint32_t numArgs);
141
142 #ifdef HAS_BINDER_SHELL_COMMAND
143 /**
144 * Process shell commands. By default, does nothing.
145 */
146 virtual inline binder_status_t handleShellCommand(int in, int out, int err, const char** argv,
147 uint32_t argc);
148 #endif
149
150 /**
151 * Interprets this binder as this underlying interface if this has stored an ICInterface in the
152 * binder's user data.
153 *
154 * This does not do type checking and should only be used when the binder is known to originate
155 * from ICInterface. Most likely, you want to use I*::fromBinder.
156 */
157 static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);
158
159 /**
160 * Helper method to create a class
161 */
162 static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
163 AIBinder_Class_onTransact onTransact);
164
165 private:
166 class ICInterfaceData {
167 public:
168 std::shared_ptr<ICInterface> interface;
169
170 static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);
171
172 static inline void* onCreate(void* args);
173 static inline void onDestroy(void* userData);
174 static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
175 uint32_t numArgs);
176
177 #ifdef HAS_BINDER_SHELL_COMMAND
178 static inline binder_status_t handleShellCommand(AIBinder* binder, int in, int out, int err,
179 const char** argv, uint32_t argc);
180 #endif
181 };
182 };
183
184 /**
185 * implementation of IInterface for server (n = native)
186 */
187 template <typename INTERFACE>
188 class BnCInterface : public INTERFACE {
189 public:
BnCInterface()190 BnCInterface() {}
~BnCInterface()191 virtual ~BnCInterface() {}
192
193 SpAIBinder asBinder() override final;
194
isRemote()195 bool isRemote() override final { return false; }
196
197 protected:
198 /**
199 * This function should only be called by asBinder. Otherwise, there is a possibility of
200 * multiple AIBinder* objects being created for the same instance of an object.
201 */
202 virtual SpAIBinder createBinder() = 0;
203
204 private:
205 std::mutex mMutex; // for asBinder
206 ScopedAIBinder_Weak mWeakBinder;
207 };
208
209 /**
210 * implementation of IInterface for client (p = proxy)
211 */
212 template <typename INTERFACE>
213 class BpCInterface : public INTERFACE {
214 public:
BpCInterface(const SpAIBinder & binder)215 explicit BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
~BpCInterface()216 virtual ~BpCInterface() {}
217
218 SpAIBinder asBinder() override final;
219
isRemote()220 bool isRemote() override final { return AIBinder_isRemote(mBinder.get()); }
221
dump(int fd,const char ** args,uint32_t numArgs)222 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override {
223 return AIBinder_dump(asBinder().get(), fd, args, numArgs);
224 }
225
226 private:
227 SpAIBinder mBinder;
228 };
229
230 // END OF CLASS DECLARATIONS
231
dump(int,const char **,uint32_t)232 binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
233 return STATUS_OK;
234 }
235
236 #ifdef HAS_BINDER_SHELL_COMMAND
handleShellCommand(int,int,int,const char **,uint32_t)237 binder_status_t ICInterface::handleShellCommand(int /*in*/, int /*out*/, int /*err*/,
238 const char** /*argv*/, uint32_t /*argc*/) {
239 return STATUS_OK;
240 }
241 #endif
242
asInterface(AIBinder * binder)243 std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
244 return ICInterfaceData::getInterface(binder);
245 }
246
defineClass(const char * interfaceDescriptor,AIBinder_Class_onTransact onTransact)247 AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
248 AIBinder_Class_onTransact onTransact) {
249 AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
250 ICInterfaceData::onDestroy, onTransact);
251 if (clazz == nullptr) {
252 return nullptr;
253 }
254
255 // We can't know if these methods are overridden by a subclass interface, so we must register
256 // ourselves. The defaults are harmless.
257 AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
258 #ifdef HAS_BINDER_SHELL_COMMAND
259 #ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
260 if (__builtin_available(android 30, *)) {
261 #else
262 if (__ANDROID_API__ >= 30) {
263 #endif
264 AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand);
265 }
266 #endif
267 return clazz;
268 }
269
270 std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
271 if (binder == nullptr) return nullptr;
272
273 void* userData = AIBinder_getUserData(binder);
274 if (userData == nullptr) return nullptr;
275
276 return static_cast<ICInterfaceData*>(userData)->interface;
277 }
278
279 void* ICInterface::ICInterfaceData::onCreate(void* args) {
280 std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
281 ICInterfaceData* data = new ICInterfaceData{interface};
282 return static_cast<void*>(data);
283 }
284
285 void ICInterface::ICInterfaceData::onDestroy(void* userData) {
286 delete static_cast<ICInterfaceData*>(userData);
287 }
288
289 binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
290 uint32_t numArgs) {
291 std::shared_ptr<ICInterface> interface = getInterface(binder);
292 return interface->dump(fd, args, numArgs);
293 }
294
295 #ifdef HAS_BINDER_SHELL_COMMAND
296 binder_status_t ICInterface::ICInterfaceData::handleShellCommand(AIBinder* binder, int in, int out,
297 int err, const char** argv,
298 uint32_t argc) {
299 std::shared_ptr<ICInterface> interface = getInterface(binder);
300 return interface->handleShellCommand(in, out, err, argv, argc);
301 }
302 #endif
303
304 template <typename INTERFACE>
305 SpAIBinder BnCInterface<INTERFACE>::asBinder() {
306 std::lock_guard<std::mutex> l(mMutex);
307
308 SpAIBinder binder;
309 if (mWeakBinder.get() != nullptr) {
310 binder.set(AIBinder_Weak_promote(mWeakBinder.get()));
311 }
312 if (binder.get() == nullptr) {
313 binder = createBinder();
314 mWeakBinder.set(AIBinder_Weak_new(binder.get()));
315 }
316
317 return binder;
318 }
319
320 template <typename INTERFACE>
321 SpAIBinder BpCInterface<INTERFACE>::asBinder() {
322 return mBinder;
323 }
324
325 } // namespace ndk
326
327 // Once minSdkVersion is 30, we are guaranteed to be building with the
328 // Android 11 AIDL compiler which supports the SharedRefBase::make API.
329 #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__)
330 namespace ndk::internal {
331 template <typename T, typename = void>
332 struct is_complete_type : std::false_type {};
333
334 template <typename T>
335 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
336 } // namespace ndk::internal
337
338 namespace std {
339
340 // Define `SharedRefBase` specific versions of `std::make_shared` and
341 // `std::make_unique` to block people from using them. Using them to allocate
342 // `ndk::SharedRefBase` objects results in double ownership. Use
343 // `ndk::SharedRefBase::make<T>(...)` instead.
344 //
345 // Note: We exclude incomplete types because `std::is_base_of` is undefined in
346 // that case.
347
348 template <typename T, typename... Args,
349 std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
350 std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
351 shared_ptr<T> make_shared(Args...) { // SEE COMMENT ABOVE.
352 static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
353 }
354
355 template <typename T, typename... Args,
356 std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
357 std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
358 unique_ptr<T> make_unique(Args...) { // SEE COMMENT ABOVE.
359 static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
360 }
361
362 } // namespace std
363 #endif
364
365 /** @} */
366