123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- /*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "BpBinder"
- //#define LOG_NDEBUG 0
- #include <binder/BpBinder.h>
- #include <binder/IPCThreadState.h>
- #include <utils/Log.h>
- #include <stdio.h>
- //#undef ALOGV
- //#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
- namespace android {
- // ---------------------------------------------------------------------------
- BpBinder::ObjectManager::ObjectManager()
- {
- }
- BpBinder::ObjectManager::~ObjectManager()
- {
- kill();
- }
- void BpBinder::ObjectManager::attach(
- const void* objectID, void* object, void* cleanupCookie,
- IBinder::object_cleanup_func func)
- {
- entry_t e;
- e.object = object;
- e.cleanupCookie = cleanupCookie;
- e.func = func;
- if (mObjects.indexOfKey(objectID) >= 0) {
- ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
- objectID, this, object);
- return;
- }
- mObjects.add(objectID, e);
- }
- void* BpBinder::ObjectManager::find(const void* objectID) const
- {
- const ssize_t i = mObjects.indexOfKey(objectID);
- if (i < 0) return NULL;
- return mObjects.valueAt(i).object;
- }
- void BpBinder::ObjectManager::detach(const void* objectID)
- {
- mObjects.removeItem(objectID);
- }
- void BpBinder::ObjectManager::kill()
- {
- const size_t N = mObjects.size();
- ALOGV("Killing %zu objects in manager %p", N, this);
- for (size_t i=0; i<N; i++) {
- const entry_t& e = mObjects.valueAt(i);
- if (e.func != NULL) {
- e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
- }
- }
- mObjects.clear();
- }
- // ---------------------------------------------------------------------------
- BpBinder::BpBinder(int32_t handle)
- : mHandle(handle)
- , mAlive(1)
- , mObitsSent(0)
- , mObituaries(NULL)
- {
- ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
- }
- bool BpBinder::isDescriptorCached() const {
- Mutex::Autolock _l(mLock);
- return mDescriptorCache.size() ? true : false;
- }
- const String16& BpBinder::getInterfaceDescriptor() const
- {
- if (isDescriptorCached() == false) {
- Parcel send, reply;
- // do the IPC without a lock held.
- status_t err = const_cast<BpBinder*>(this)->transact(
- INTERFACE_TRANSACTION, send, &reply);
- if (err == NO_ERROR) {
- String16 res(reply.readString16());
- Mutex::Autolock _l(mLock);
- // mDescriptorCache could have been assigned while the lock was
- // released.
- if (mDescriptorCache.size() == 0)
- mDescriptorCache = res;
- }
- }
- // we're returning a reference to a non-static object here. Usually this
- // is not something smart to do, however, with binder objects it is
- // (usually) safe because they are reference-counted.
- return mDescriptorCache;
- }
- bool BpBinder::isBinderAlive() const
- {
- return mAlive != 0;
- }
- status_t BpBinder::pingBinder()
- {
- Parcel send;
- Parcel reply;
- status_t err = transact(PING_TRANSACTION, send, &reply);
- if (err != NO_ERROR) return err;
- if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
- return (status_t)reply.readInt32();
- }
- status_t BpBinder::dump(int fd, const Vector<String16>& args)
- {
- Parcel send;
- Parcel reply;
- send.writeFileDescriptor(fd);
- const size_t numArgs = args.size();
- send.writeInt32(numArgs);
- for (size_t i = 0; i < numArgs; i++) {
- send.writeString16(args[i]);
- }
- status_t err = transact(DUMP_TRANSACTION, send, &reply);
- return err;
- }
- status_t BpBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- // Once a binder has died, it will never come back to life.
- if (mAlive) {
- status_t status = IPCThreadState::self()->transact(
- mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
- return status;
- }
- return DEAD_OBJECT;
- }
- status_t BpBinder::linkToDeath(
- const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
- {
- Obituary ob;
- ob.recipient = recipient;
- ob.cookie = cookie;
- ob.flags = flags;
- LOG_ALWAYS_FATAL_IF(recipient == NULL,
- "linkToDeath(): recipient must be non-NULL");
- {
- AutoMutex _l(mLock);
- if (!mObitsSent) {
- if (!mObituaries) {
- mObituaries = new Vector<Obituary>;
- if (!mObituaries) {
- return NO_MEMORY;
- }
- ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
- getWeakRefs()->incWeak(this);
- IPCThreadState* self = IPCThreadState::self();
- self->requestDeathNotification(mHandle, this);
- self->flushCommands();
- }
- ssize_t res = mObituaries->add(ob);
- return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
- }
- }
- return DEAD_OBJECT;
- }
- status_t BpBinder::unlinkToDeath(
- const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
- wp<DeathRecipient>* outRecipient)
- {
- AutoMutex _l(mLock);
- if (mObitsSent) {
- return DEAD_OBJECT;
- }
- const size_t N = mObituaries ? mObituaries->size() : 0;
- for (size_t i=0; i<N; i++) {
- const Obituary& obit = mObituaries->itemAt(i);
- if ((obit.recipient == recipient
- || (recipient == NULL && obit.cookie == cookie))
- && obit.flags == flags) {
- if (outRecipient != NULL) {
- *outRecipient = mObituaries->itemAt(i).recipient;
- }
- mObituaries->removeAt(i);
- if (mObituaries->size() == 0) {
- ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- delete mObituaries;
- mObituaries = NULL;
- }
- return NO_ERROR;
- }
- }
- return NAME_NOT_FOUND;
- }
- void BpBinder::sendObituary()
- {
- ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
- this, mHandle, mObitsSent ? "true" : "false");
- mAlive = 0;
- if (mObitsSent) return;
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
- IPCThreadState* self = IPCThreadState::self();
- self->clearDeathNotification(mHandle, this);
- self->flushCommands();
- mObituaries = NULL;
- }
- mObitsSent = 1;
- mLock.unlock();
- ALOGV("Reporting death of proxy %p for %zu recipients\n",
- this, obits ? obits->size() : 0U);
- if (obits != NULL) {
- const size_t N = obits->size();
- for (size_t i=0; i<N; i++) {
- reportOneDeath(obits->itemAt(i));
- }
- delete obits;
- }
- }
- void BpBinder::reportOneDeath(const Obituary& obit)
- {
- sp<DeathRecipient> recipient = obit.recipient.promote();
- ALOGV("Reporting death to recipient: %p\n", recipient.get());
- if (recipient == NULL) return;
- recipient->binderDied(this);
- }
- void BpBinder::attachObject(
- const void* objectID, void* object, void* cleanupCookie,
- object_cleanup_func func)
- {
- AutoMutex _l(mLock);
- ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
- mObjects.attach(objectID, object, cleanupCookie, func);
- }
- void* BpBinder::findObject(const void* objectID) const
- {
- AutoMutex _l(mLock);
- return mObjects.find(objectID);
- }
- void BpBinder::detachObject(const void* objectID)
- {
- AutoMutex _l(mLock);
- mObjects.detach(objectID);
- }
- BpBinder* BpBinder::remoteBinder()
- {
- return this;
- }
- BpBinder::~BpBinder()
- {
- ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- mLock.lock();
- Vector<Obituary>* obits = mObituaries;
- if(obits != NULL) {
- if (ipc) ipc->clearDeathNotification(mHandle, this);
- mObituaries = NULL;
- }
- mLock.unlock();
- if (obits != NULL) {
- // XXX Should we tell any remaining DeathRecipient
- // objects that the last strong ref has gone away, so they
- // are no longer linked?
- delete obits;
- }
- if (ipc) {
- ipc->expungeHandle(mHandle, this);
- ipc->decWeakHandle(mHandle);
- }
- }
- void BpBinder::onFirstRef()
- {
- ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->incStrongHandle(mHandle);
- }
- void BpBinder::onLastStrongRef(const void* /*id*/)
- {
- ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
- IF_ALOGV() {
- printRefs();
- }
- IPCThreadState* ipc = IPCThreadState::self();
- if (ipc) ipc->decStrongHandle(mHandle);
- }
- bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
- {
- ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
- IPCThreadState* ipc = IPCThreadState::self();
- return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
- }
- // ---------------------------------------------------------------------------
- }; // namespace android
|