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