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 <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 NULL;
47 }
48 
remoteBinder()49 BpHwBinder* IBinder::remoteBinder()
50 {
51     return NULL;
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     Mutex mLock;
65     BpHwBinder::ObjectManager mObjects;
66 };
67 
68 // ---------------------------------------------------------------------------
69 
BHwBinder()70 BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr)
71 {
72 }
73 
getMinSchedulingPolicy()74 int BHwBinder::getMinSchedulingPolicy() {
75     return mSchedPolicy;
76 }
77 
getMinSchedulingPriority()78 int BHwBinder::getMinSchedulingPriority() {
79     return mSchedPriority;
80 }
81 
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags,TransactCallback callback)82 status_t BHwBinder::transact(
83     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
84 {
85     data.setDataPosition(0);
86 
87     status_t err = NO_ERROR;
88     switch (code) {
89         default:
90             err = onTransact(code, data, reply, flags,
91                     [&](auto &replyParcel) {
92                         replyParcel.setDataPosition(0);
93                         if (callback != NULL) {
94                             callback(replyParcel);
95                         }
96                     });
97             break;
98     }
99 
100     return err;
101 }
102 
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)103 status_t BHwBinder::linkToDeath(
104     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
105     uint32_t /*flags*/)
106 {
107     return INVALID_OPERATION;
108 }
109 
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)110 status_t BHwBinder::unlinkToDeath(
111     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
112     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
113 {
114     return INVALID_OPERATION;
115 }
116 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)117 void BHwBinder::attachObject(
118     const void* objectID, void* object, void* cleanupCookie,
119     object_cleanup_func func)
120 {
121     Extras* e = mExtras.load(std::memory_order_acquire);
122 
123     if (!e) {
124         e = new Extras;
125         Extras* expected = nullptr;
126         if (!mExtras.compare_exchange_strong(expected, e,
127                                              std::memory_order_release,
128                                              std::memory_order_acquire)) {
129             delete e;
130             e = expected;  // Filled in by CAS
131         }
132         if (e == 0) return; // out of memory
133     }
134 
135     AutoMutex _l(e->mLock);
136     e->mObjects.attach(objectID, object, cleanupCookie, func);
137 }
138 
findObject(const void * objectID) const139 void* BHwBinder::findObject(const void* objectID) const
140 {
141     Extras* e = mExtras.load(std::memory_order_acquire);
142     if (!e) return NULL;
143 
144     AutoMutex _l(e->mLock);
145     return e->mObjects.find(objectID);
146 }
147 
detachObject(const void * objectID)148 void BHwBinder::detachObject(const void* objectID)
149 {
150     Extras* e = mExtras.load(std::memory_order_acquire);
151     if (!e) return;
152 
153     AutoMutex _l(e->mLock);
154     e->mObjects.detach(objectID);
155 }
156 
localBinder()157 BHwBinder* BHwBinder::localBinder()
158 {
159     return this;
160 }
161 
~BHwBinder()162 BHwBinder::~BHwBinder()
163 {
164     Extras* e = mExtras.load(std::memory_order_relaxed);
165     if (e) delete e;
166 }
167 
168 
onTransact(uint32_t,const Parcel &,Parcel *,uint32_t,TransactCallback)169 status_t BHwBinder::onTransact(
170     uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
171     TransactCallback /*callback*/)
172 {
173     return UNKNOWN_TRANSACTION;
174 }
175 
176 // ---------------------------------------------------------------------------
177 
178 enum {
179     // This is used to transfer ownership of the remote binder from
180     // the BpHwRefBase object holding it (when it is constructed), to the
181     // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
182     kRemoteAcquired = 0x00000001
183 };
184 
BpHwRefBase(const sp<IBinder> & o)185 BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
186     : mRemote(o.get()), mRefs(NULL), mState(0)
187 {
188     if (mRemote) {
189         mRemote->incStrong(this);           // Removed on first IncStrong().
190     }
191 }
192 
~BpHwRefBase()193 BpHwRefBase::~BpHwRefBase()
194 {
195     if (mRemote) {
196         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
197             mRemote->decStrong(this);
198         }
199     }
200 }
201 
onFirstRef()202 void BpHwRefBase::onFirstRef()
203 {
204     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
205 }
206 
onLastStrongRef(const void *)207 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
208 {
209     if (mRemote) {
210         mRemote->decStrong(this);
211     }
212 }
213 
onIncStrongAttempted(uint32_t,const void *)214 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
215 {
216     return false;
217 }
218 
219 // ---------------------------------------------------------------------------
220 
221 }; // namespace hardware
222 }; // namespace android
223