Binder.cpp revision c5b2c0bf8007562536b822eb060fc54a01f8e08b
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 <binder/Binder.h> 18 19#include <utils/Atomic.h> 20#include <binder/BpBinder.h> 21#include <binder/IInterface.h> 22#include <binder/Parcel.h> 23 24#include <stdio.h> 25 26namespace android { 27 28// --------------------------------------------------------------------------- 29 30sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) 31{ 32 return NULL; 33} 34 35BBinder* IBinder::localBinder() 36{ 37 return NULL; 38} 39 40BpBinder* IBinder::remoteBinder() 41{ 42 return NULL; 43} 44 45bool IBinder::checkSubclass(const void* /*subclassID*/) const 46{ 47 return false; 48} 49 50// --------------------------------------------------------------------------- 51 52class BBinder::Extras 53{ 54public: 55 Mutex mLock; 56 BpBinder::ObjectManager mObjects; 57}; 58 59// --------------------------------------------------------------------------- 60 61BBinder::BBinder() 62 : mExtras(NULL) 63{ 64} 65 66bool BBinder::isBinderAlive() const 67{ 68 return true; 69} 70 71status_t BBinder::pingBinder() 72{ 73 return NO_ERROR; 74} 75 76String16 BBinder::getInterfaceDescriptor() const 77{ 78 LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this); 79 return String16(); 80} 81 82status_t BBinder::transact( 83 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 84{ 85 data.setDataPosition(0); 86 87 status_t err = NO_ERROR; 88 switch (code) { 89 case PING_TRANSACTION: 90 reply->writeInt32(pingBinder()); 91 break; 92 default: 93 err = onTransact(code, data, reply, flags); 94 break; 95 } 96 97 if (reply != NULL) { 98 reply->setDataPosition(0); 99 } 100 101 return err; 102} 103 104status_t BBinder::linkToDeath( 105 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 106{ 107 return INVALID_OPERATION; 108} 109 110status_t BBinder::unlinkToDeath( 111 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 112 wp<DeathRecipient>* outRecipient) 113{ 114 return INVALID_OPERATION; 115} 116 117status_t BBinder::dump(int fd, const Vector<String16>& args) 118{ 119 return NO_ERROR; 120} 121 122void BBinder::attachObject( 123 const void* objectID, void* object, void* cleanupCookie, 124 object_cleanup_func func) 125{ 126 Extras* e = mExtras; 127 128 if (!e) { 129 e = new Extras; 130 if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e), 131 reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) { 132 delete e; 133 e = mExtras; 134 } 135 if (e == 0) return; // out of memory 136 } 137 138 AutoMutex _l(e->mLock); 139 e->mObjects.attach(objectID, object, cleanupCookie, func); 140} 141 142void* BBinder::findObject(const void* objectID) const 143{ 144 Extras* e = mExtras; 145 if (!e) return NULL; 146 147 AutoMutex _l(e->mLock); 148 return e->mObjects.find(objectID); 149} 150 151void BBinder::detachObject(const void* objectID) 152{ 153 Extras* e = mExtras; 154 if (!e) return; 155 156 AutoMutex _l(e->mLock); 157 e->mObjects.detach(objectID); 158} 159 160BBinder* BBinder::localBinder() 161{ 162 return this; 163} 164 165BBinder::~BBinder() 166{ 167 if (mExtras) delete mExtras; 168} 169 170 171status_t BBinder::onTransact( 172 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 173{ 174 switch (code) { 175 case INTERFACE_TRANSACTION: 176 reply->writeString16(getInterfaceDescriptor()); 177 return NO_ERROR; 178 179 case DUMP_TRANSACTION: { 180 int fd = data.readFileDescriptor(); 181 int argc = data.readInt32(); 182 Vector<String16> args; 183 for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 184 args.add(data.readString16()); 185 } 186 return dump(fd, args); 187 } 188 default: 189 return UNKNOWN_TRANSACTION; 190 } 191} 192 193// --------------------------------------------------------------------------- 194 195enum { 196 // This is used to transfer ownership of the remote binder from 197 // the BpRefBase object holding it (when it is constructed), to the 198 // owner of the BpRefBase object when it first acquires that BpRefBase. 199 kRemoteAcquired = 0x00000001 200}; 201 202BpRefBase::BpRefBase(const sp<IBinder>& o) 203 : mRemote(o.get()), mRefs(NULL), mState(0) 204{ 205 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 206 207 if (mRemote) { 208 mRemote->incStrong(this); // Removed on first IncStrong(). 209 mRefs = mRemote->createWeak(this); // Held for our entire lifetime. 210 } 211} 212 213BpRefBase::~BpRefBase() 214{ 215 if (mRemote) { 216 if (!(mState&kRemoteAcquired)) { 217 mRemote->decStrong(this); 218 } 219 mRefs->decWeak(this); 220 } 221} 222 223void BpRefBase::onFirstRef() 224{ 225 android_atomic_or(kRemoteAcquired, &mState); 226} 227 228void BpRefBase::onLastStrongRef(const void* id) 229{ 230 if (mRemote) { 231 mRemote->decStrong(this); 232 } 233} 234 235bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id) 236{ 237 return mRemote ? mRefs->attemptIncStrong(this) : false; 238} 239 240// --------------------------------------------------------------------------- 241 242}; // namespace android 243