2 * Copyright (C) 2005 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "BpBinder"
18 //#define LOG_NDEBUG 0
20 #include <binder/BpBinder.h>
22 #include <binder/IPCThreadState.h>
23 #include <binder/IResultReceiver.h>
24 #include <utils/Log.h>
29 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
33 // ---------------------------------------------------------------------------
35 BpBinder::ObjectManager::ObjectManager()
39 BpBinder::ObjectManager::~ObjectManager()
44 void BpBinder::ObjectManager::attach(
45 const void* objectID, void* object, void* cleanupCookie,
46 IBinder::object_cleanup_func func)
50 e.cleanupCookie = cleanupCookie;
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);
59 mObjects.add(objectID, e);
62 void* BpBinder::ObjectManager::find(const void* objectID) const
64 const ssize_t i = mObjects.indexOfKey(objectID);
65 if (i < 0) return NULL;
66 return mObjects.valueAt(i).object;
69 void BpBinder::ObjectManager::detach(const void* objectID)
71 mObjects.removeItem(objectID);
74 void BpBinder::ObjectManager::kill()
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);
81 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
88 // ---------------------------------------------------------------------------
90 BpBinder::BpBinder(int32_t handle)
96 ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
98 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
99 IPCThreadState::self()->incWeakHandle(handle);
102 bool BpBinder::isDescriptorCached() const {
103 Mutex::Autolock _l(mLock);
104 return mDescriptorCache.size() ? true : false;
107 const String16& BpBinder::getInterfaceDescriptor() const
109 if (isDescriptorCached() == false) {
111 // do the IPC without a lock held.
112 status_t err = const_cast<BpBinder*>(this)->transact(
113 INTERFACE_TRANSACTION, send, &reply);
114 if (err == NO_ERROR) {
115 String16 res(reply.readString16());
116 Mutex::Autolock _l(mLock);
117 // mDescriptorCache could have been assigned while the lock was
119 if (mDescriptorCache.size() == 0)
120 mDescriptorCache = res;
124 // we're returning a reference to a non-static object here. Usually this
125 // is not something smart to do, however, with binder objects it is
126 // (usually) safe because they are reference-counted.
128 return mDescriptorCache;
131 bool BpBinder::isBinderAlive() const
136 status_t BpBinder::pingBinder()
140 status_t err = transact(PING_TRANSACTION, send, &reply);
141 if (err != NO_ERROR) return err;
142 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
143 return (status_t)reply.readInt32();
146 status_t BpBinder::dump(int fd, const Vector<String16>& args)
150 send.writeFileDescriptor(fd);
151 const size_t numArgs = args.size();
152 send.writeInt32(numArgs);
153 for (size_t i = 0; i < numArgs; i++) {
154 send.writeString16(args[i]);
156 status_t err = transact(DUMP_TRANSACTION, send, &reply);
160 status_t BpBinder::transact(
161 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
163 // Once a binder has died, it will never come back to life.
165 status_t status = IPCThreadState::self()->transact(
166 mHandle, code, data, reply, flags);
167 if (status == DEAD_OBJECT) mAlive = 0;
174 status_t BpBinder::linkToDeath(
175 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
178 ob.recipient = recipient;
182 LOG_ALWAYS_FATAL_IF(recipient == NULL,
183 "linkToDeath(): recipient must be non-NULL");
190 mObituaries = new Vector<Obituary>;
194 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
195 getWeakRefs()->incWeak(this);
196 IPCThreadState* self = IPCThreadState::self();
197 self->requestDeathNotification(mHandle, this);
198 self->flushCommands();
200 ssize_t res = mObituaries->add(ob);
201 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
208 status_t BpBinder::unlinkToDeath(
209 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
210 wp<DeathRecipient>* outRecipient)
218 const size_t N = mObituaries ? mObituaries->size() : 0;
219 for (size_t i=0; i<N; i++) {
220 const Obituary& obit = mObituaries->itemAt(i);
221 if ((obit.recipient == recipient
222 || (recipient == NULL && obit.cookie == cookie))
223 && obit.flags == flags) {
224 if (outRecipient != NULL) {
225 *outRecipient = mObituaries->itemAt(i).recipient;
227 mObituaries->removeAt(i);
228 if (mObituaries->size() == 0) {
229 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
230 IPCThreadState* self = IPCThreadState::self();
231 self->clearDeathNotification(mHandle, this);
232 self->flushCommands();
240 return NAME_NOT_FOUND;
243 void BpBinder::sendObituary()
245 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
246 this, mHandle, mObitsSent ? "true" : "false");
249 if (mObitsSent) return;
252 Vector<Obituary>* obits = mObituaries;
254 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
255 IPCThreadState* self = IPCThreadState::self();
256 self->clearDeathNotification(mHandle, this);
257 self->flushCommands();
263 ALOGV("Reporting death of proxy %p for %zu recipients\n",
264 this, obits ? obits->size() : 0U);
267 const size_t N = obits->size();
268 for (size_t i=0; i<N; i++) {
269 reportOneDeath(obits->itemAt(i));
276 void BpBinder::reportOneDeath(const Obituary& obit)
278 sp<DeathRecipient> recipient = obit.recipient.promote();
279 ALOGV("Reporting death to recipient: %p\n", recipient.get());
280 if (recipient == NULL) return;
282 recipient->binderDied(this);
286 void BpBinder::attachObject(
287 const void* objectID, void* object, void* cleanupCookie,
288 object_cleanup_func func)
291 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
292 mObjects.attach(objectID, object, cleanupCookie, func);
295 void* BpBinder::findObject(const void* objectID) const
298 return mObjects.find(objectID);
301 void BpBinder::detachObject(const void* objectID)
304 mObjects.detach(objectID);
307 BpBinder* BpBinder::remoteBinder()
312 BpBinder::~BpBinder()
314 ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
316 IPCThreadState* ipc = IPCThreadState::self();
319 Vector<Obituary>* obits = mObituaries;
321 if (ipc) ipc->clearDeathNotification(mHandle, this);
327 // XXX Should we tell any remaining DeathRecipient
328 // objects that the last strong ref has gone away, so they
329 // are no longer linked?
334 ipc->expungeHandle(mHandle, this);
335 ipc->decWeakHandle(mHandle);
339 void BpBinder::onFirstRef()
341 ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
342 IPCThreadState* ipc = IPCThreadState::self();
343 if (ipc) ipc->incStrongHandle(mHandle);
346 void BpBinder::onLastStrongRef(const void* /*id*/)
348 ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
352 IPCThreadState* ipc = IPCThreadState::self();
353 if (ipc) ipc->decStrongHandle(mHandle);
356 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
358 ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
359 IPCThreadState* ipc = IPCThreadState::self();
360 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
363 // ---------------------------------------------------------------------------
365 }; // namespace android