blob: 345ba20f1b022e444871cc1dd1381689deb32d48 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070020#include <binder/BpBinder.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080021
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070022#include <binder/IPCThreadState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080023#include <utils/Log.h>
24
25#include <stdio.h>
26
Steve Block6807e592011-10-20 11:56:00 +010027//#undef ALOGV
28//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080029
30namespace android {
31
32// ---------------------------------------------------------------------------
33
34BpBinder::ObjectManager::ObjectManager()
35{
36}
37
38BpBinder::ObjectManager::~ObjectManager()
39{
40 kill();
41}
42
43void 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) {
Steve Blocke6f43dd2012-01-06 19:20:56 +000053 ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080054 objectID, this, object);
55 return;
56 }
57
58 mObjects.add(objectID, e);
59}
60
61void* 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
68void BpBinder::ObjectManager::detach(const void* objectID)
69{
70 mObjects.removeItem(objectID);
71}
72
73void BpBinder::ObjectManager::kill()
74{
75 const size_t N = mObjects.size();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -070076 ALOGV("Killing %zu objects in manager %p", N, this);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080077 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
89BpBinder::BpBinder(int32_t handle)
90 : mHandle(handle)
91 , mAlive(1)
92 , mObitsSent(0)
93 , mObituaries(NULL)
94{
Steve Block6807e592011-10-20 11:56:00 +010095 ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080096
97 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
98 IPCThreadState::self()->incWeakHandle(handle);
99}
100
Mathias Agopian83c04462009-05-22 19:00:22 -0700101bool BpBinder::isDescriptorCached() const {
102 Mutex::Autolock _l(mLock);
103 return mDescriptorCache.size() ? true : false;
104}
105
106const String16& BpBinder::getInterfaceDescriptor() const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800107{
Mathias Agopian83c04462009-05-22 19:00:22 -0700108 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 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800121 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700122
Mathias Agopian83c04462009-05-22 19:00:22 -0700123 // we're returning a reference to a non-static object here. Usually this
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700124 // is not something smart to do, however, with binder objects it is
Mathias Agopian83c04462009-05-22 19:00:22 -0700125 // (usually) safe because they are reference-counted.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700126
Mathias Agopian83c04462009-05-22 19:00:22 -0700127 return mDescriptorCache;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800128}
129
130bool BpBinder::isBinderAlive() const
131{
132 return mAlive != 0;
133}
134
135status_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
145status_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
159status_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
173status_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 }
Steve Block6807e592011-10-20 11:56:00 +0100193 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800194 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
207status_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) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800223 if (outRecipient != NULL) {
224 *outRecipient = mObituaries->itemAt(i).recipient;
225 }
226 mObituaries->removeAt(i);
227 if (mObituaries->size() == 0) {
Steve Block6807e592011-10-20 11:56:00 +0100228 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800229 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
242void BpBinder::sendObituary()
243{
Steve Block6807e592011-10-20 11:56:00 +0100244 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800245 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) {
Steve Block6807e592011-10-20 11:56:00 +0100253 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800254 IPCThreadState* self = IPCThreadState::self();
255 self->clearDeathNotification(mHandle, this);
256 self->flushCommands();
257 mObituaries = NULL;
258 }
259 mObitsSent = 1;
260 mLock.unlock();
261
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700262 ALOGV("Reporting death of proxy %p for %zu recipients\n",
263 this, obits ? obits->size() : 0U);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800264
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
275void BpBinder::reportOneDeath(const Obituary& obit)
276{
277 sp<DeathRecipient> recipient = obit.recipient.promote();
Steve Block6807e592011-10-20 11:56:00 +0100278 ALOGV("Reporting death to recipient: %p\n", recipient.get());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800279 if (recipient == NULL) return;
280
281 recipient->binderDied(this);
282}
283
284
285void BpBinder::attachObject(
286 const void* objectID, void* object, void* cleanupCookie,
287 object_cleanup_func func)
288{
289 AutoMutex _l(mLock);
Steve Block6807e592011-10-20 11:56:00 +0100290 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800291 mObjects.attach(objectID, object, cleanupCookie, func);
292}
293
294void* BpBinder::findObject(const void* objectID) const
295{
296 AutoMutex _l(mLock);
297 return mObjects.find(objectID);
298}
299
300void BpBinder::detachObject(const void* objectID)
301{
302 AutoMutex _l(mLock);
303 mObjects.detach(objectID);
304}
305
306BpBinder* BpBinder::remoteBinder()
307{
308 return this;
309}
310
311BpBinder::~BpBinder()
312{
Steve Block6807e592011-10-20 11:56:00 +0100313 ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800314
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
338void BpBinder::onFirstRef()
339{
Steve Block6807e592011-10-20 11:56:00 +0100340 ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800341 IPCThreadState* ipc = IPCThreadState::self();
342 if (ipc) ipc->incStrongHandle(mHandle);
343}
344
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800345void BpBinder::onLastStrongRef(const void* /*id*/)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800346{
Steve Block6807e592011-10-20 11:56:00 +0100347 ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
348 IF_ALOGV() {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800349 printRefs();
350 }
351 IPCThreadState* ipc = IPCThreadState::self();
352 if (ipc) ipc->decStrongHandle(mHandle);
353}
354
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800355bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800356{
Steve Block6807e592011-10-20 11:56:00 +0100357 ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800358 IPCThreadState* ipc = IPCThreadState::self();
359 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
360}
361
362// ---------------------------------------------------------------------------
363
364}; // namespace android