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 #define LOG_TAG "hw-BpHwBinder"
18 //#define LOG_NDEBUG 0
19
20 #include <hwbinder/BpHwBinder.h>
21
22 #include <hwbinder/IPCThreadState.h>
23 #include <utils/Log.h>
24
25 #include <stdio.h>
26
27 //#undef ALOGV
28 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
29
30 namespace android {
31 namespace hardware {
32
33 // ---------------------------------------------------------------------------
34
ObjectManager()35 BpHwBinder::ObjectManager::ObjectManager()
36 {
37 }
38
~ObjectManager()39 BpHwBinder::ObjectManager::~ObjectManager()
40 {
41 kill();
42 }
43
attach(const void * objectID,void * object,void * cleanupCookie,IBinder::object_cleanup_func func)44 void BpHwBinder::ObjectManager::attach(
45 const void* objectID, void* object, void* cleanupCookie,
46 IBinder::object_cleanup_func func)
47 {
48 entry_t e;
49 e.object = object;
50 e.cleanupCookie = cleanupCookie;
51 e.func = func;
52
53 if (mObjects.indexOfKey(objectID) >= 0) {
54 ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
55 objectID, this, object);
56 return;
57 }
58
59 mObjects.add(objectID, e);
60 }
61
find(const void * objectID) const62 void* BpHwBinder::ObjectManager::find(const void* objectID) const
63 {
64 const ssize_t i = mObjects.indexOfKey(objectID);
65 if (i < 0) return nullptr;
66 return mObjects.valueAt(i).object;
67 }
68
detach(const void * objectID)69 void BpHwBinder::ObjectManager::detach(const void* objectID)
70 {
71 mObjects.removeItem(objectID);
72 }
73
kill()74 void BpHwBinder::ObjectManager::kill()
75 {
76 const size_t N = mObjects.size();
77 ALOGV("Killing %zu objects in manager %p", N, this);
78 for (size_t i=0; i<N; i++) {
79 const entry_t& e = mObjects.valueAt(i);
80 if (e.func != nullptr) {
81 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
82 }
83 }
84
85 mObjects.clear();
86 }
87
88 // ---------------------------------------------------------------------------
89
BpHwBinder(int32_t handle)90 BpHwBinder::BpHwBinder(int32_t handle)
91 : mHandle(handle)
92 , mAlive(1)
93 , mObitsSent(0)
94 , mObituaries(nullptr)
95 {
96 ALOGV("Creating BpHwBinder %p handle %d\n", this, mHandle);
97
98 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
99 IPCThreadState::self()->incWeakHandle(handle, this);
100 }
101
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags,TransactCallback)102 status_t BpHwBinder::transact(
103 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback /*callback*/)
104 {
105 // Once a binder has died, it will never come back to life.
106 if (mAlive) {
107 status_t status = IPCThreadState::self()->transact(
108 mHandle, code, data, reply, flags);
109 if (status == DEAD_OBJECT) mAlive = 0;
110 return status;
111 }
112
113 return DEAD_OBJECT;
114 }
115
linkToDeath(const sp<DeathRecipient> & recipient,void * cookie,uint32_t flags)116 status_t BpHwBinder::linkToDeath(
117 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
118 {
119 Obituary ob;
120 ob.recipient = recipient;
121 ob.cookie = cookie;
122 ob.flags = flags;
123
124 LOG_ALWAYS_FATAL_IF(recipient == nullptr,
125 "linkToDeath(): recipient must be non-NULL");
126
127 {
128 AutoMutex _l(mLock);
129
130 if (!mObitsSent) {
131 if (!mObituaries) {
132 mObituaries = new Vector<Obituary>;
133 if (!mObituaries) {
134 return NO_MEMORY;
135 }
136 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
137 getWeakRefs()->incWeak(this);
138 IPCThreadState* self = IPCThreadState::self();
139 self->requestDeathNotification(mHandle, this);
140 self->flushCommands();
141 }
142 ssize_t res = mObituaries->add(ob);
143 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
144 }
145 }
146
147 return DEAD_OBJECT;
148 }
149
unlinkToDeath(const wp<DeathRecipient> & recipient,void * cookie,uint32_t flags,wp<DeathRecipient> * outRecipient)150 status_t BpHwBinder::unlinkToDeath(
151 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
152 wp<DeathRecipient>* outRecipient)
153 {
154 AutoMutex _l(mLock);
155
156 if (mObitsSent) {
157 return DEAD_OBJECT;
158 }
159
160 const size_t N = mObituaries ? mObituaries->size() : 0;
161 for (size_t i=0; i<N; i++) {
162 const Obituary& obit = mObituaries->itemAt(i);
163 if ((obit.recipient == recipient
164 || (recipient == nullptr && obit.cookie == cookie))
165 && obit.flags == flags) {
166 if (outRecipient != nullptr) {
167 *outRecipient = mObituaries->itemAt(i).recipient;
168 }
169 mObituaries->removeAt(i);
170 if (mObituaries->size() == 0) {
171 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
172 IPCThreadState* self = IPCThreadState::self();
173 self->clearDeathNotification(mHandle, this);
174 self->flushCommands();
175 delete mObituaries;
176 mObituaries = nullptr;
177 }
178 return NO_ERROR;
179 }
180 }
181
182 return NAME_NOT_FOUND;
183 }
184
sendObituary()185 void BpHwBinder::sendObituary()
186 {
187 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
188 this, mHandle, mObitsSent ? "true" : "false");
189
190 mAlive = 0;
191 if (mObitsSent) return;
192
193 mLock.lock();
194 Vector<Obituary>* obits = mObituaries;
195 if(obits != nullptr) {
196 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
197 IPCThreadState* self = IPCThreadState::self();
198 self->clearDeathNotification(mHandle, this);
199 self->flushCommands();
200 mObituaries = nullptr;
201 }
202 mObitsSent = 1;
203 mLock.unlock();
204
205 ALOGV("Reporting death of proxy %p for %zu recipients\n",
206 this, obits ? obits->size() : 0U);
207
208 if (obits != nullptr) {
209 const size_t N = obits->size();
210 for (size_t i=0; i<N; i++) {
211 reportOneDeath(obits->itemAt(i));
212 }
213
214 delete obits;
215 }
216 }
217
218 // Returns the strong refcount on the object this proxy points to, or
219 // -1 in case of failure.
getNodeStrongRefCount()220 ssize_t BpHwBinder::getNodeStrongRefCount()
221 {
222 return ProcessState::self()->getStrongRefCountForNodeByHandle(mHandle);
223 }
224
reportOneDeath(const Obituary & obit)225 void BpHwBinder::reportOneDeath(const Obituary& obit)
226 {
227 sp<DeathRecipient> recipient = obit.recipient.promote();
228 ALOGV("Reporting death to recipient: %p\n", recipient.get());
229 if (recipient == nullptr) return;
230
231 recipient->binderDied(this);
232 }
233
234
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)235 void BpHwBinder::attachObject(
236 const void* objectID, void* object, void* cleanupCookie,
237 object_cleanup_func func)
238 {
239 AutoMutex _l(mLock);
240 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
241 mObjects.attach(objectID, object, cleanupCookie, func);
242 }
243
findObject(const void * objectID) const244 void* BpHwBinder::findObject(const void* objectID) const
245 {
246 AutoMutex _l(mLock);
247 return mObjects.find(objectID);
248 }
249
detachObject(const void * objectID)250 void BpHwBinder::detachObject(const void* objectID)
251 {
252 AutoMutex _l(mLock);
253 mObjects.detach(objectID);
254 }
255
remoteBinder()256 BpHwBinder* BpHwBinder::remoteBinder()
257 {
258 return this;
259 }
260
~BpHwBinder()261 BpHwBinder::~BpHwBinder()
262 {
263 ALOGV("Destroying BpHwBinder %p handle %d\n", this, mHandle);
264
265 IPCThreadState* ipc = IPCThreadState::self();
266
267 mLock.lock();
268 Vector<Obituary>* obits = mObituaries;
269 if(obits != nullptr) {
270 if (ipc) ipc->clearDeathNotification(mHandle, this);
271 mObituaries = nullptr;
272 }
273 mLock.unlock();
274
275 if (obits != nullptr) {
276 // XXX Should we tell any remaining DeathRecipient
277 // objects that the last strong ref has gone away, so they
278 // are no longer linked?
279 delete obits;
280 }
281
282 if (ipc) {
283 ipc->expungeHandle(mHandle, this);
284 ipc->decWeakHandle(mHandle);
285 }
286 }
287
onFirstRef()288 void BpHwBinder::onFirstRef()
289 {
290 ALOGV("onFirstRef BpHwBinder %p handle %d\n", this, mHandle);
291 IPCThreadState* ipc = IPCThreadState::self();
292 if (ipc) ipc->incStrongHandle(mHandle, this);
293 }
294
onLastStrongRef(const void *)295 void BpHwBinder::onLastStrongRef(const void* /*id*/)
296 {
297 ALOGV("onLastStrongRef BpHwBinder %p handle %d\n", this, mHandle);
298 IF_ALOGV() {
299 printRefs();
300 }
301 IPCThreadState* ipc = IPCThreadState::self();
302 if (ipc) {
303 ipc->decStrongHandle(mHandle);
304 ipc->flushCommands();
305 }
306 }
307
onIncStrongAttempted(uint32_t,const void *)308 bool BpHwBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
309 {
310 ALOGV("onIncStrongAttempted BpHwBinder %p handle %d\n", this, mHandle);
311 IPCThreadState* ipc = IPCThreadState::self();
312 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
313 }
314
315 // ---------------------------------------------------------------------------
316
317 }; // namespace hardware
318 }; // namespace android
319