1 /*
2  * Copyright (C) 2005 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 #include <hwbinder/Binder.h>
18 
19 #include <atomic>
20 #include <utils/misc.h>
21 #include <hwbinder/BpHwBinder.h>
22 #include <hwbinder/IInterface.h>
23 #include <hwbinder/Parcel.h>
24 
25 #include <linux/sched.h>
26 #include <stdio.h>
27 
28 namespace android {
29 namespace hardware {
30 
31 // ---------------------------------------------------------------------------
32 
IBinder()33 IBinder::IBinder()
34     : RefBase()
35 {
36 }
37 
~IBinder()38 IBinder::~IBinder()
39 {
40 }
41 
42 // ---------------------------------------------------------------------------
43 
localBinder()44 BHwBinder* IBinder::localBinder()
45 {
46     return nullptr;
47 }
48 
remoteBinder()49 BpHwBinder* IBinder::remoteBinder()
50 {
51     return nullptr;
52 }
53 
checkSubclass(const void *) const54 bool IBinder::checkSubclass(const void* /*subclassID*/) const
55 {
56     return false;
57 }
58 
59 // ---------------------------------------------------------------------------
60 
61 class BHwBinder::Extras
62 {
63 public:
64     // unlocked objects
65     bool mRequestingSid = false;
66 
67     // for below objects
68     Mutex mLock;
69     BpHwBinder::ObjectManager mObjects;
70 };
71 
72 // ---------------------------------------------------------------------------
73 
BHwBinder()74 BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr)
75 {
76 }
77 
getMinSchedulingPolicy()78 int BHwBinder::getMinSchedulingPolicy() {
79     return mSchedPolicy;
80 }
81 
getMinSchedulingPriority()82 int BHwBinder::getMinSchedulingPriority() {
83     return mSchedPriority;
84 }
85 
isRequestingSid()86 bool BHwBinder::isRequestingSid() {
87     Extras* e = mExtras.load(std::memory_order_acquire);
88 
89     return e && e->mRequestingSid;
90 }
91 
setRequestingSid(bool requestingSid)92 void BHwBinder::setRequestingSid(bool requestingSid) {
93     Extras* e = mExtras.load(std::memory_order_acquire);
94 
95     if (!e) {
96         // default is false. Most things don't need sids, so avoiding allocations when possible.
97         if (!requestingSid) {
98             return;
99         }
100 
101         e = getOrCreateExtras();
102         if (!e) return; // out of memory
103     }
104 
105     e->mRequestingSid = requestingSid;
106 }
107 
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags,TransactCallback callback)108 status_t BHwBinder::transact(
109     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
110 {
111     data.setDataPosition(0);
112 
113     status_t err = NO_ERROR;
114     switch (code) {
115         default:
116             err = onTransact(code, data, reply, flags,
117                     [&](auto &replyParcel) {
118                         replyParcel.setDataPosition(0);
119                         if (callback != nullptr) {
120                             callback(replyParcel);
121                         }
122                     });
123             break;
124     }
125 
126     return err;
127 }
128 
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)129 status_t BHwBinder::linkToDeath(
130     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
131     uint32_t /*flags*/)
132 {
133     return INVALID_OPERATION;
134 }
135 
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)136 status_t BHwBinder::unlinkToDeath(
137     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
138     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
139 {
140     return INVALID_OPERATION;
141 }
142 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)143 void BHwBinder::attachObject(
144     const void* objectID, void* object, void* cleanupCookie,
145     object_cleanup_func func)
146 {
147     Extras* e = getOrCreateExtras();
148     if (!e) return; // out of memory
149 
150     AutoMutex _l(e->mLock);
151     e->mObjects.attach(objectID, object, cleanupCookie, func);
152 }
153 
findObject(const void * objectID) const154 void* BHwBinder::findObject(const void* objectID) const
155 {
156     Extras* e = mExtras.load(std::memory_order_acquire);
157     if (!e) return nullptr;
158 
159     AutoMutex _l(e->mLock);
160     return e->mObjects.find(objectID);
161 }
162 
detachObject(const void * objectID)163 void BHwBinder::detachObject(const void* objectID)
164 {
165     Extras* e = mExtras.load(std::memory_order_acquire);
166     if (!e) return;
167 
168     AutoMutex _l(e->mLock);
169     e->mObjects.detach(objectID);
170 }
171 
localBinder()172 BHwBinder* BHwBinder::localBinder()
173 {
174     return this;
175 }
176 
~BHwBinder()177 BHwBinder::~BHwBinder()
178 {
179     Extras* e = mExtras.load(std::memory_order_relaxed);
180     if (e) delete e;
181 }
182 
183 
onTransact(uint32_t,const Parcel &,Parcel *,uint32_t,TransactCallback)184 status_t BHwBinder::onTransact(
185     uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
186     TransactCallback /*callback*/)
187 {
188     return UNKNOWN_TRANSACTION;
189 }
190 
getOrCreateExtras()191 BHwBinder::Extras* BHwBinder::getOrCreateExtras()
192 {
193     Extras* e = mExtras.load(std::memory_order_acquire);
194 
195     if (!e) {
196         e = new Extras;
197         Extras* expected = nullptr;
198         if (!mExtras.compare_exchange_strong(expected, e,
199                                              std::memory_order_release,
200                                              std::memory_order_acquire)) {
201             delete e;
202             e = expected;  // Filled in by CAS
203         }
204         if (e == nullptr) return nullptr; // out of memory
205     }
206 
207     return e;
208 }
209 
210 // ---------------------------------------------------------------------------
211 
212 enum {
213     // This is used to transfer ownership of the remote binder from
214     // the BpHwRefBase object holding it (when it is constructed), to the
215     // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
216     kRemoteAcquired = 0x00000001
217 };
218 
BpHwRefBase(const sp<IBinder> & o)219 BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
220     : mRemote(o.get()), mRefs(nullptr), mState(0)
221 {
222     if (mRemote) {
223         mRemote->incStrong(this);           // Removed on first IncStrong().
224     }
225 }
226 
~BpHwRefBase()227 BpHwRefBase::~BpHwRefBase()
228 {
229     if (mRemote) {
230         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
231             mRemote->decStrong(this);
232         }
233     }
234 }
235 
onFirstRef()236 void BpHwRefBase::onFirstRef()
237 {
238     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
239 }
240 
onLastStrongRef(const void *)241 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
242 {
243     if (mRemote) {
244         mRemote->decStrong(this);
245     }
246 }
247 
onIncStrongAttempted(uint32_t,const void *)248 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
249 {
250     return false;
251 }
252 
253 // ---------------------------------------------------------------------------
254 
255 } // namespace hardware
256 } // namespace android
257