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