diff options
author | Mathias Agopian <mathias@google.com> | 2009-05-18 15:08:03 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-05-20 12:55:02 -0700 |
commit | 25ba5b6564224dceefa086b5c439ef28dad530ca (patch) | |
tree | af3c9fa40d27425c37cf6492589cb86854b08f8a /libs/binder/Binder.cpp | |
parent | 6b961bb54bfb44abd1bcee46924ca38c2d10dd72 (diff) | |
download | frameworks_base-25ba5b6564224dceefa086b5c439ef28dad530ca.zip frameworks_base-25ba5b6564224dceefa086b5c439ef28dad530ca.tar.gz frameworks_base-25ba5b6564224dceefa086b5c439ef28dad530ca.tar.bz2 |
checkpoint: split libutils into libutils + libbinder
Diffstat (limited to 'libs/binder/Binder.cpp')
-rw-r--r-- | libs/binder/Binder.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp new file mode 100644 index 0000000..37e4685 --- /dev/null +++ b/libs/binder/Binder.cpp @@ -0,0 +1,242 @@ +/* + * 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. + */ + +#include <utils/Binder.h> + +#include <utils/Atomic.h> +#include <utils/BpBinder.h> +#include <utils/IInterface.h> +#include <utils/Parcel.h> + +#include <stdio.h> + +namespace android { + +// --------------------------------------------------------------------------- + +sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) +{ + return NULL; +} + +BBinder* IBinder::localBinder() +{ + return NULL; +} + +BpBinder* IBinder::remoteBinder() +{ + return NULL; +} + +bool IBinder::checkSubclass(const void* /*subclassID*/) const +{ + return false; +} + +// --------------------------------------------------------------------------- + +class BBinder::Extras +{ +public: + Mutex mLock; + BpBinder::ObjectManager mObjects; +}; + +// --------------------------------------------------------------------------- + +BBinder::BBinder() + : mExtras(NULL) +{ +} + +bool BBinder::isBinderAlive() const +{ + return true; +} + +status_t BBinder::pingBinder() +{ + return NO_ERROR; +} + +String16 BBinder::getInterfaceDescriptor() const +{ + LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this); + return String16(); +} + +status_t BBinder::transact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + data.setDataPosition(0); + + status_t err = NO_ERROR; + switch (code) { + case PING_TRANSACTION: + reply->writeInt32(pingBinder()); + break; + default: + err = onTransact(code, data, reply, flags); + break; + } + + if (reply != NULL) { + reply->setDataPosition(0); + } + + return err; +} + +status_t BBinder::linkToDeath( + const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) +{ + return INVALID_OPERATION; +} + +status_t BBinder::unlinkToDeath( + const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, + wp<DeathRecipient>* outRecipient) +{ + return INVALID_OPERATION; +} + +status_t BBinder::dump(int fd, const Vector<String16>& args) +{ + return NO_ERROR; +} + +void BBinder::attachObject( + const void* objectID, void* object, void* cleanupCookie, + object_cleanup_func func) +{ + Extras* e = mExtras; + + if (!e) { + e = new Extras; + if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e), + reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) { + delete e; + e = mExtras; + } + if (e == 0) return; // out of memory + } + + AutoMutex _l(e->mLock); + e->mObjects.attach(objectID, object, cleanupCookie, func); +} + +void* BBinder::findObject(const void* objectID) const +{ + Extras* e = mExtras; + if (!e) return NULL; + + AutoMutex _l(e->mLock); + return e->mObjects.find(objectID); +} + +void BBinder::detachObject(const void* objectID) +{ + Extras* e = mExtras; + if (!e) return; + + AutoMutex _l(e->mLock); + e->mObjects.detach(objectID); +} + +BBinder* BBinder::localBinder() +{ + return this; +} + +BBinder::~BBinder() +{ + if (mExtras) delete mExtras; +} + + +status_t BBinder::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch (code) { + case INTERFACE_TRANSACTION: + reply->writeString16(getInterfaceDescriptor()); + return NO_ERROR; + + case DUMP_TRANSACTION: { + int fd = data.readFileDescriptor(); + int argc = data.readInt32(); + Vector<String16> args; + for (int i = 0; i < argc && data.dataAvail() > 0; i++) { + args.add(data.readString16()); + } + return dump(fd, args); + } + default: + return UNKNOWN_TRANSACTION; + } +} + +// --------------------------------------------------------------------------- + +enum { + // This is used to transfer ownership of the remote binder from + // the BpRefBase object holding it (when it is constructed), to the + // owner of the BpRefBase object when it first acquires that BpRefBase. + kRemoteAcquired = 0x00000001 +}; + +BpRefBase::BpRefBase(const sp<IBinder>& o) + : mRemote(o.get()), mRefs(NULL), mState(0) +{ + extendObjectLifetime(OBJECT_LIFETIME_WEAK); + + if (mRemote) { + mRemote->incStrong(this); // Removed on first IncStrong(). + mRefs = mRemote->createWeak(this); // Held for our entire lifetime. + } +} + +BpRefBase::~BpRefBase() +{ + if (mRemote) { + if (!(mState&kRemoteAcquired)) { + mRemote->decStrong(this); + } + mRefs->decWeak(this); + } +} + +void BpRefBase::onFirstRef() +{ + android_atomic_or(kRemoteAcquired, &mState); +} + +void BpRefBase::onLastStrongRef(const void* id) +{ + if (mRemote) { + mRemote->decStrong(this); + } +} + +bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id) +{ + return mRemote ? mRefs->attemptIncStrong(this) : false; +} + +// --------------------------------------------------------------------------- + +}; // namespace android |