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 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
189
190 if (mRemote) {
191 mRemote->incStrong(this); // Removed on first IncStrong().
192 mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
193 }
194 }
195
~BpHwRefBase()196 BpHwRefBase::~BpHwRefBase()
197 {
198 if (mRemote) {
199 if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
200 mRemote->decStrong(this);
201 }
202 mRefs->decWeak(this);
203 }
204 }
205
onFirstRef()206 void BpHwRefBase::onFirstRef()
207 {
208 mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
209 }
210
onLastStrongRef(const void *)211 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
212 {
213 if (mRemote) {
214 mRemote->decStrong(this);
215 }
216 }
217
onIncStrongAttempted(uint32_t,const void *)218 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
219 {
220 return mRemote ? mRefs->attemptIncStrong(this) : false;
221 }
222
223 // ---------------------------------------------------------------------------
224
225 }; // namespace hardware
226 }; // namespace android
227