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 "BpBinder"
18 //#define LOG_NDEBUG 0
19 
20 #include <binder/BpBinder.h>
21 
22 #include <binder/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 
32 // ---------------------------------------------------------------------------
33 
ObjectManager()34 BpBinder::ObjectManager::ObjectManager()
35 {
36 }
37 
~ObjectManager()38 BpBinder::ObjectManager::~ObjectManager()
39 {
40     kill();
41 }
42 
attach(const void * objectID,void * object,void * cleanupCookie,IBinder::object_cleanup_func func)43 void BpBinder::ObjectManager::attach(
44     const void* objectID, void* object, void* cleanupCookie,
45     IBinder::object_cleanup_func func)
46 {
47     entry_t e;
48     e.object = object;
49     e.cleanupCookie = cleanupCookie;
50     e.func = func;
51 
52     if (mObjects.indexOfKey(objectID) >= 0) {
53         ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
54                 objectID, this,  object);
55         return;
56     }
57 
58     mObjects.add(objectID, e);
59 }
60 
find(const void * objectID) const61 void* BpBinder::ObjectManager::find(const void* objectID) const
62 {
63     const ssize_t i = mObjects.indexOfKey(objectID);
64     if (i < 0) return NULL;
65     return mObjects.valueAt(i).object;
66 }
67 
detach(const void * objectID)68 void BpBinder::ObjectManager::detach(const void* objectID)
69 {
70     mObjects.removeItem(objectID);
71 }
72 
kill()73 void BpBinder::ObjectManager::kill()
74 {
75     const size_t N = mObjects.size();
76     ALOGV("Killing %zu objects in manager %p", N, this);
77     for (size_t i=0; i<N; i++) {
78         const entry_t& e = mObjects.valueAt(i);
79         if (e.func != NULL) {
80             e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
81         }
82     }
83 
84     mObjects.clear();
85 }
86 
87 // ---------------------------------------------------------------------------
88 
BpBinder(int32_t handle)89 BpBinder::BpBinder(int32_t handle)
90     : mHandle(handle)
91     , mAlive(1)
92     , mObitsSent(0)
93     , mObituaries(NULL)
94 {
95     ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
96 
97     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
98     IPCThreadState::self()->incWeakHandle(handle);
99 }
100 
isDescriptorCached() const101 bool BpBinder::isDescriptorCached() const {
102     Mutex::Autolock _l(mLock);
103     return mDescriptorCache.size() ? true : false;
104 }
105 
getInterfaceDescriptor() const106 const String16& BpBinder::getInterfaceDescriptor() const
107 {
108     if (isDescriptorCached() == false) {
109         Parcel send, reply;
110         // do the IPC without a lock held.
111         status_t err = const_cast<BpBinder*>(this)->transact(
112                 INTERFACE_TRANSACTION, send, &reply);
113         if (err == NO_ERROR) {
114             String16 res(reply.readString16());
115             Mutex::Autolock _l(mLock);
116             // mDescriptorCache could have been assigned while the lock was
117             // released.
118             if (mDescriptorCache.size() == 0)
119                 mDescriptorCache = res;
120         }
121     }
122 
123     // we're returning a reference to a non-static object here. Usually this
124     // is not something smart to do, however, with binder objects it is
125     // (usually) safe because they are reference-counted.
126 
127     return mDescriptorCache;
128 }
129 
isBinderAlive() const130 bool BpBinder::isBinderAlive() const
131 {
132     return mAlive != 0;
133 }
134 
pingBinder()135 status_t BpBinder::pingBinder()
136 {
137     Parcel send;
138     Parcel reply;
139     status_t err = transact(PING_TRANSACTION, send, &reply);
140     if (err != NO_ERROR) return err;
141     if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA;
142     return (status_t)reply.readInt32();
143 }
144 
dump(int fd,const Vector<String16> & args)145 status_t BpBinder::dump(int fd, const Vector<String16>& args)
146 {
147     Parcel send;
148     Parcel reply;
149     send.writeFileDescriptor(fd);
150     const size_t numArgs = args.size();
151     send.writeInt32(numArgs);
152     for (size_t i = 0; i < numArgs; i++) {
153         send.writeString16(args[i]);
154     }
155     status_t err = transact(DUMP_TRANSACTION, send, &reply);
156     return err;
157 }
158 
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)159 status_t BpBinder::transact(
160     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
161 {
162     // Once a binder has died, it will never come back to life.
163     if (mAlive) {
164         status_t status = IPCThreadState::self()->transact(
165             mHandle, code, data, reply, flags);
166         if (status == DEAD_OBJECT) mAlive = 0;
167         return status;
168     }
169 
170     return DEAD_OBJECT;
171 }
172 
linkToDeath(const sp<DeathRecipient> & recipient,void * cookie,uint32_t flags)173 status_t BpBinder::linkToDeath(
174     const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
175 {
176     Obituary ob;
177     ob.recipient = recipient;
178     ob.cookie = cookie;
179     ob.flags = flags;
180 
181     LOG_ALWAYS_FATAL_IF(recipient == NULL,
182                         "linkToDeath(): recipient must be non-NULL");
183 
184     {
185         AutoMutex _l(mLock);
186 
187         if (!mObitsSent) {
188             if (!mObituaries) {
189                 mObituaries = new Vector<Obituary>;
190                 if (!mObituaries) {
191                     return NO_MEMORY;
192                 }
193                 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
194                 getWeakRefs()->incWeak(this);
195                 IPCThreadState* self = IPCThreadState::self();
196                 self->requestDeathNotification(mHandle, this);
197                 self->flushCommands();
198             }
199             ssize_t res = mObituaries->add(ob);
200             return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;
201         }
202     }
203 
204     return DEAD_OBJECT;
205 }
206 
unlinkToDeath(const wp<DeathRecipient> & recipient,void * cookie,uint32_t flags,wp<DeathRecipient> * outRecipient)207 status_t BpBinder::unlinkToDeath(
208     const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
209     wp<DeathRecipient>* outRecipient)
210 {
211     AutoMutex _l(mLock);
212 
213     if (mObitsSent) {
214         return DEAD_OBJECT;
215     }
216 
217     const size_t N = mObituaries ? mObituaries->size() : 0;
218     for (size_t i=0; i<N; i++) {
219         const Obituary& obit = mObituaries->itemAt(i);
220         if ((obit.recipient == recipient
221                     || (recipient == NULL && obit.cookie == cookie))
222                 && obit.flags == flags) {
223             if (outRecipient != NULL) {
224                 *outRecipient = mObituaries->itemAt(i).recipient;
225             }
226             mObituaries->removeAt(i);
227             if (mObituaries->size() == 0) {
228                 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
229                 IPCThreadState* self = IPCThreadState::self();
230                 self->clearDeathNotification(mHandle, this);
231                 self->flushCommands();
232                 delete mObituaries;
233                 mObituaries = NULL;
234             }
235             return NO_ERROR;
236         }
237     }
238 
239     return NAME_NOT_FOUND;
240 }
241 
sendObituary()242 void BpBinder::sendObituary()
243 {
244     ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
245         this, mHandle, mObitsSent ? "true" : "false");
246 
247     mAlive = 0;
248     if (mObitsSent) return;
249 
250     mLock.lock();
251     Vector<Obituary>* obits = mObituaries;
252     if(obits != NULL) {
253         ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
254         IPCThreadState* self = IPCThreadState::self();
255         self->clearDeathNotification(mHandle, this);
256         self->flushCommands();
257         mObituaries = NULL;
258     }
259     mObitsSent = 1;
260     mLock.unlock();
261 
262     ALOGV("Reporting death of proxy %p for %zu recipients\n",
263         this, obits ? obits->size() : 0U);
264 
265     if (obits != NULL) {
266         const size_t N = obits->size();
267         for (size_t i=0; i<N; i++) {
268             reportOneDeath(obits->itemAt(i));
269         }
270 
271         delete obits;
272     }
273 }
274 
reportOneDeath(const Obituary & obit)275 void BpBinder::reportOneDeath(const Obituary& obit)
276 {
277     sp<DeathRecipient> recipient = obit.recipient.promote();
278     ALOGV("Reporting death to recipient: %p\n", recipient.get());
279     if (recipient == NULL) return;
280 
281     recipient->binderDied(this);
282 }
283 
284 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)285 void BpBinder::attachObject(
286     const void* objectID, void* object, void* cleanupCookie,
287     object_cleanup_func func)
288 {
289     AutoMutex _l(mLock);
290     ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
291     mObjects.attach(objectID, object, cleanupCookie, func);
292 }
293 
findObject(const void * objectID) const294 void* BpBinder::findObject(const void* objectID) const
295 {
296     AutoMutex _l(mLock);
297     return mObjects.find(objectID);
298 }
299 
detachObject(const void * objectID)300 void BpBinder::detachObject(const void* objectID)
301 {
302     AutoMutex _l(mLock);
303     mObjects.detach(objectID);
304 }
305 
remoteBinder()306 BpBinder* BpBinder::remoteBinder()
307 {
308     return this;
309 }
310 
~BpBinder()311 BpBinder::~BpBinder()
312 {
313     ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
314 
315     IPCThreadState* ipc = IPCThreadState::self();
316 
317     mLock.lock();
318     Vector<Obituary>* obits = mObituaries;
319     if(obits != NULL) {
320         if (ipc) ipc->clearDeathNotification(mHandle, this);
321         mObituaries = NULL;
322     }
323     mLock.unlock();
324 
325     if (obits != NULL) {
326         // XXX Should we tell any remaining DeathRecipient
327         // objects that the last strong ref has gone away, so they
328         // are no longer linked?
329         delete obits;
330     }
331 
332     if (ipc) {
333         ipc->expungeHandle(mHandle, this);
334         ipc->decWeakHandle(mHandle);
335     }
336 }
337 
onFirstRef()338 void BpBinder::onFirstRef()
339 {
340     ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
341     IPCThreadState* ipc = IPCThreadState::self();
342     if (ipc) ipc->incStrongHandle(mHandle);
343 }
344 
onLastStrongRef(const void *)345 void BpBinder::onLastStrongRef(const void* /*id*/)
346 {
347     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
348     IF_ALOGV() {
349         printRefs();
350     }
351     IPCThreadState* ipc = IPCThreadState::self();
352     if (ipc) ipc->decStrongHandle(mHandle);
353 }
354 
onIncStrongAttempted(uint32_t,const void *)355 bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
356 {
357     ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
358     IPCThreadState* ipc = IPCThreadState::self();
359     return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
360 }
361 
362 // ---------------------------------------------------------------------------
363 
364 }; // namespace android
365