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