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      * This method is not given ownership of the FD.
143      */
144     virtual inline binder_status_t dump(int fd, const char** args, uint32_t numArgs);
145 
146 #ifdef HAS_BINDER_SHELL_COMMAND
147     /**
148      * Process shell commands. By default, does nothing.
149      */
150     virtual inline binder_status_t handleShellCommand(int in, int out, int err, const char** argv,
151                                                       uint32_t argc);
152 #endif
153 
154     /**
155      * Interprets this binder as this underlying interface if this has stored an ICInterface in the
156      * binder's user data.
157      *
158      * This does not do type checking and should only be used when the binder is known to originate
159      * from ICInterface. Most likely, you want to use I*::fromBinder.
160      */
161     static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);
162 
163     /**
164      * Helper method to create a class
165      */
166     static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
167                                               AIBinder_Class_onTransact onTransact);
168 
169    private:
170     class ICInterfaceData {
171        public:
172         std::shared_ptr<ICInterface> interface;
173 
174         static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);
175 
176         static inline void* onCreate(void* args);
177         static inline void onDestroy(void* userData);
178         static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
179                                              uint32_t numArgs);
180 
181 #ifdef HAS_BINDER_SHELL_COMMAND
182         static inline binder_status_t handleShellCommand(AIBinder* binder, int in, int out, int err,
183                                                          const char** argv, uint32_t argc);
184 #endif
185     };
186 };
187 
188 /**
189  * implementation of IInterface for server (n = native)
190  */
191 template <typename INTERFACE>
192 class BnCInterface : public INTERFACE {
193    public:
BnCInterface()194     BnCInterface() {}
~BnCInterface()195     virtual ~BnCInterface() {}
196 
197     SpAIBinder asBinder() override final;
198 
isRemote()199     bool isRemote() override final { return false; }
200 
makeServiceName(std::string_view instance)201     static std::string makeServiceName(std::string_view instance) {
202         return INTERFACE::descriptor + ("/" + std::string(instance));
203     }
204 
205    protected:
206     /**
207      * This function should only be called by asBinder. Otherwise, there is a possibility of
208      * multiple AIBinder* objects being created for the same instance of an object.
209      */
210     virtual SpAIBinder createBinder() = 0;
211 
212    private:
213     std::mutex mMutex;  // for asBinder
214     ScopedAIBinder_Weak mWeakBinder;
215 };
216 
217 /**
218  * implementation of IInterface for client (p = proxy)
219  */
220 template <typename INTERFACE>
221 class BpCInterface : public INTERFACE {
222    public:
BpCInterface(const SpAIBinder & binder)223     explicit BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
~BpCInterface()224     virtual ~BpCInterface() {}
225 
226     SpAIBinder asBinder() override final;
227 
isRemote()228     bool isRemote() override final { return AIBinder_isRemote(mBinder.get()); }
229 
dump(int fd,const char ** args,uint32_t numArgs)230     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override {
231         return AIBinder_dump(asBinder().get(), fd, args, numArgs);
232     }
233 
234    private:
235     SpAIBinder mBinder;
236 };
237 
238 // END OF CLASS DECLARATIONS
239 
dump(int,const char **,uint32_t)240 binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
241     return STATUS_OK;
242 }
243 
244 #ifdef HAS_BINDER_SHELL_COMMAND
handleShellCommand(int,int,int,const char **,uint32_t)245 binder_status_t ICInterface::handleShellCommand(int /*in*/, int /*out*/, int /*err*/,
246                                                 const char** /*argv*/, uint32_t /*argc*/) {
247     return STATUS_OK;
248 }
249 #endif
250 
asInterface(AIBinder * binder)251 std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
252     return ICInterfaceData::getInterface(binder);
253 }
254 
defineClass(const char * interfaceDescriptor,AIBinder_Class_onTransact onTransact)255 AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
256                                          AIBinder_Class_onTransact onTransact) {
257     AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
258                                                   ICInterfaceData::onDestroy, onTransact);
259     if (clazz == nullptr) {
260         return nullptr;
261     }
262 
263     // We can't know if these methods are overridden by a subclass interface, so we must register
264     // ourselves. The defaults are harmless.
265     AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
266 #ifdef HAS_BINDER_SHELL_COMMAND
267 #ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
268     if (__builtin_available(android 30, *)) {
269 #else
270     if (__ANDROID_API__ >= 30) {
271 #endif
272         AIBinder_Class_setHandleShellCommand(clazz, ICInterfaceData::handleShellCommand);
273     }
274 #endif
275     return clazz;
276 }
277 
278 std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
279     if (binder == nullptr) return nullptr;
280 
281     void* userData = AIBinder_getUserData(binder);
282     if (userData == nullptr) return nullptr;
283 
284     return static_cast<ICInterfaceData*>(userData)->interface;
285 }
286 
287 void* ICInterface::ICInterfaceData::onCreate(void* args) {
288     std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
289     ICInterfaceData* data = new ICInterfaceData{interface};
290     return static_cast<void*>(data);
291 }
292 
293 void ICInterface::ICInterfaceData::onDestroy(void* userData) {
294     delete static_cast<ICInterfaceData*>(userData);
295 }
296 
297 binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
298                                                      uint32_t numArgs) {
299     std::shared_ptr<ICInterface> interface = getInterface(binder);
300     if (interface != nullptr) {
301         return interface->dump(fd, args, numArgs);
302     }
303     return STATUS_DEAD_OBJECT;
304 }
305 
306 #ifdef HAS_BINDER_SHELL_COMMAND
307 binder_status_t ICInterface::ICInterfaceData::handleShellCommand(AIBinder* binder, int in, int out,
308                                                                  int err, const char** argv,
309                                                                  uint32_t argc) {
310     std::shared_ptr<ICInterface> interface = getInterface(binder);
311     if (interface != nullptr) {
312         return interface->handleShellCommand(in, out, err, argv, argc);
313     }
314     return STATUS_DEAD_OBJECT;
315 }
316 #endif
317 
318 template <typename INTERFACE>
319 SpAIBinder BnCInterface<INTERFACE>::asBinder() {
320     std::lock_guard<std::mutex> l(mMutex);
321 
322     SpAIBinder binder;
323     if (mWeakBinder.get() != nullptr) {
324         binder.set(AIBinder_Weak_promote(mWeakBinder.get()));
325     }
326     if (binder.get() == nullptr) {
327         binder = createBinder();
328         mWeakBinder.set(AIBinder_Weak_new(binder.get()));
329     }
330 
331     return binder;
332 }
333 
334 template <typename INTERFACE>
335 SpAIBinder BpCInterface<INTERFACE>::asBinder() {
336     return mBinder;
337 }
338 
339 }  // namespace ndk
340 
341 // Once minSdkVersion is 30, we are guaranteed to be building with the
342 // Android 11 AIDL compiler which supports the SharedRefBase::make API.
343 #if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__)
344 namespace ndk::internal {
345 template <typename T, typename = void>
346 struct is_complete_type : std::false_type {};
347 
348 template <typename T>
349 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
350 }  // namespace ndk::internal
351 
352 namespace std {
353 
354 // Define `SharedRefBase` specific versions of `std::make_shared` and
355 // `std::make_unique` to block people from using them. Using them to allocate
356 // `ndk::SharedRefBase` objects results in double ownership. Use
357 // `ndk::SharedRefBase::make<T>(...)` instead.
358 //
359 // Note: We exclude incomplete types because `std::is_base_of` is undefined in
360 // that case.
361 
362 template <typename T, typename... Args,
363           std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
364           std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
365 shared_ptr<T> make_shared(Args...) {  // SEE COMMENT ABOVE.
366     static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
367 }
368 
369 template <typename T, typename... Args,
370           std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
371           std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
372 unique_ptr<T> make_unique(Args...) {  // SEE COMMENT ABOVE.
373     static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
374 }
375 
376 }  // namespace std
377 #endif
378 
379 /** @} */
380