• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <assert.h>
34 
35 #include <memory>
36 #include <mutex>
37 
38 namespace ndk {
39 
40 /**
41  * analog using std::shared_ptr for internally held refcount
42  *
43  * ref must be called at least one time during the lifetime of this object. The recommended way to
44  * construct this object is with SharedRefBase::make.
45  */
46 class SharedRefBase {
47    public:
SharedRefBase()48     SharedRefBase() {}
~SharedRefBase()49     virtual ~SharedRefBase() {
50         std::call_once(mFlagThis, [&]() {
51             __assert(__FILE__, __LINE__, "SharedRefBase: no ref created during lifetime");
52         });
53     }
54 
55     /**
56      * A shared_ptr must be held to this object when this is called. This must be called once during
57      * the lifetime of this object.
58      */
ref()59     std::shared_ptr<SharedRefBase> ref() {
60         std::shared_ptr<SharedRefBase> thiz = mThis.lock();
61 
62         std::call_once(mFlagThis, [&]() { mThis = thiz = std::shared_ptr<SharedRefBase>(this); });
63 
64         return thiz;
65     }
66 
67     /**
68      * Convenience method for a ref (see above) which automatically casts to the desired child type.
69      */
70     template <typename CHILD>
ref()71     std::shared_ptr<CHILD> ref() {
72         return std::static_pointer_cast<CHILD>(ref());
73     }
74 
75     /**
76      * Convenience method for making an object directly with a reference.
77      */
78     template <class T, class... Args>
make(Args &&...args)79     static std::shared_ptr<T> make(Args&&... args) {
80         T* t = new T(std::forward<Args>(args)...);
81         return t->template ref<T>();
82     }
83 
84    private:
85     std::once_flag mFlagThis;
86     std::weak_ptr<SharedRefBase> mThis;
87 };
88 
89 /**
90  * wrapper analog to IInterface
91  */
92 class ICInterface : public SharedRefBase {
93    public:
ICInterface()94     ICInterface() {}
~ICInterface()95     virtual ~ICInterface() {}
96 
97     /**
98      * This either returns the single existing implementation or creates a new implementation.
99      */
100     virtual SpAIBinder asBinder() = 0;
101 
102     /**
103      * Returns whether this interface is in a remote process. If it cannot be determined locally,
104      * this will be checked using AIBinder_isRemote.
105      */
106     virtual bool isRemote() = 0;
107 
108     /**
109      * Dumps information about the interface. By default, dumps nothing.
110      */
111     virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
112 
113     /**
114      * Interprets this binder as this underlying interface if this has stored an ICInterface in the
115      * binder's user data.
116      *
117      * This does not do type checking and should only be used when the binder is known to originate
118      * from ICInterface. Most likely, you want to use I*::fromBinder.
119      */
120     static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);
121 
122     /**
123      * Helper method to create a class
124      */
125     static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
126                                               AIBinder_Class_onTransact onTransact);
127 
128    private:
129     class ICInterfaceData {
130        public:
131         std::shared_ptr<ICInterface> interface;
132 
133         static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);
134 
135         static inline void* onCreate(void* args);
136         static inline void onDestroy(void* userData);
137         static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
138                                              uint32_t numArgs);
139     };
140 };
141 
142 /**
143  * implementation of IInterface for server (n = native)
144  */
145 template <typename INTERFACE>
146 class BnCInterface : public INTERFACE {
147    public:
BnCInterface()148     BnCInterface() {}
~BnCInterface()149     virtual ~BnCInterface() {}
150 
151     SpAIBinder asBinder() override;
152 
isRemote()153     bool isRemote() override { return false; }
154 
155    protected:
156     /**
157      * This function should only be called by asBinder. Otherwise, there is a possibility of
158      * multiple AIBinder* objects being created for the same instance of an object.
159      */
160     virtual SpAIBinder createBinder() = 0;
161 
162    private:
163     std::mutex mMutex;  // for asBinder
164     ScopedAIBinder_Weak mWeakBinder;
165 };
166 
167 /**
168  * implementation of IInterface for client (p = proxy)
169  */
170 template <typename INTERFACE>
171 class BpCInterface : public INTERFACE {
172    public:
BpCInterface(const SpAIBinder & binder)173     explicit BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
~BpCInterface()174     virtual ~BpCInterface() {}
175 
176     SpAIBinder asBinder() override;
177 
isRemote()178     bool isRemote() override { return AIBinder_isRemote(mBinder.get()); }
179 
dump(int fd,const char ** args,uint32_t numArgs)180     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override {
181         return AIBinder_dump(asBinder().get(), fd, args, numArgs);
182     }
183 
184    private:
185     SpAIBinder mBinder;
186 };
187 
188 // END OF CLASS DECLARATIONS
189 
dump(int,const char **,uint32_t)190 binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
191     return STATUS_OK;
192 }
193 
asInterface(AIBinder * binder)194 std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
195     return ICInterfaceData::getInterface(binder);
196 }
197 
defineClass(const char * interfaceDescriptor,AIBinder_Class_onTransact onTransact)198 AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
199                                          AIBinder_Class_onTransact onTransact) {
200     AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
201                                                   ICInterfaceData::onDestroy, onTransact);
202     if (clazz == nullptr) {
203         return nullptr;
204     }
205 
206     // We can't know if this method is overriden by a subclass interface, so we must register
207     // ourselves. The default (nothing to dump) is harmless.
208     AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
209     return clazz;
210 }
211 
getInterface(AIBinder * binder)212 std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
213     if (binder == nullptr) return nullptr;
214 
215     void* userData = AIBinder_getUserData(binder);
216     if (userData == nullptr) return nullptr;
217 
218     return static_cast<ICInterfaceData*>(userData)->interface;
219 }
220 
onCreate(void * args)221 void* ICInterface::ICInterfaceData::onCreate(void* args) {
222     std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
223     ICInterfaceData* data = new ICInterfaceData{interface};
224     return static_cast<void*>(data);
225 }
226 
onDestroy(void * userData)227 void ICInterface::ICInterfaceData::onDestroy(void* userData) {
228     delete static_cast<ICInterfaceData*>(userData);
229 }
230 
onDump(AIBinder * binder,int fd,const char ** args,uint32_t numArgs)231 binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
232                                                      uint32_t numArgs) {
233     std::shared_ptr<ICInterface> interface = getInterface(binder);
234     return interface->dump(fd, args, numArgs);
235 }
236 
237 template <typename INTERFACE>
asBinder()238 SpAIBinder BnCInterface<INTERFACE>::asBinder() {
239     std::lock_guard<std::mutex> l(mMutex);
240 
241     SpAIBinder binder;
242     if (mWeakBinder.get() != nullptr) {
243         binder.set(AIBinder_Weak_promote(mWeakBinder.get()));
244     }
245     if (binder.get() == nullptr) {
246         binder = createBinder();
247         mWeakBinder.set(AIBinder_Weak_new(binder.get()));
248     }
249 
250     return binder;
251 }
252 
253 template <typename INTERFACE>
asBinder()254 SpAIBinder BpCInterface<INTERFACE>::asBinder() {
255     return mBinder;
256 }
257 
258 }  // namespace ndk
259 
260 /** @} */
261